From 400d625090257ad3a24a0f5ad4b6edded624a607 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sat, 2 Jul 2022 11:36:02 -0400 Subject: [PATCH 1/9] Add improved short-name code to bevy_utils --- crates/bevy_utils/src/lib.rs | 2 + crates/bevy_utils/src/short_names.rs | 105 +++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 crates/bevy_utils/src/short_names.rs diff --git a/crates/bevy_utils/src/lib.rs b/crates/bevy_utils/src/lib.rs index 0f425be909b95..2b09fdbf0f3b2 100644 --- a/crates/bevy_utils/src/lib.rs +++ b/crates/bevy_utils/src/lib.rs @@ -4,6 +4,8 @@ pub mod prelude { pub mod futures; pub mod label; +mod short_names; +pub use short_names::get_short_name; mod default; mod float_ord; diff --git a/crates/bevy_utils/src/short_names.rs b/crates/bevy_utils/src/short_names.rs new file mode 100644 index 0000000000000..25b2b5e71891a --- /dev/null +++ b/crates/bevy_utils/src/short_names.rs @@ -0,0 +1,105 @@ +/// Collapses a name returned by [`std::any::type_name`] to remove its module path +pub fn get_short_name(full_name: &str) -> String { + // Generics result in nested paths within <..> blocks + // Consider "bevy_render::camera::camera::extract_cameras" + // To tackle this, we parse the string from left to right, collapsing as we go + let mut index: usize = 0; + let end_of_string = full_name.len(); + let mut parsed_name = String::new(); + + while index < end_of_string { + let rest_of_string = full_name.get(index..end_of_string).unwrap_or_default(); + + // Collapse everything up to the next special character, + // then skip over it + if let Some(special_character_index) = rest_of_string.find(|c: char| { + (c == ' ') + || (c == '<') + || (c == '>') + || (c == '(') + || (c == ')') + || (c == '[') + || (c == ']') + || (c == ',') + || (c == ';') + }) { + let segment_to_collapse = rest_of_string + .get(0..special_character_index) + .unwrap_or_default(); + parsed_name += collapse_type_name(segment_to_collapse); + // Insert the special character + let special_character = + &rest_of_string[special_character_index..=special_character_index]; + parsed_name.push_str(special_character); + // Move the index just past the special character + index += special_character_index + 1; + } else { + // If there are no special characters left, we're done! + parsed_name += collapse_type_name(rest_of_string); + index = end_of_string; + } + } + parsed_name +} + +#[inline(always)] +fn collapse_type_name(string: &str) -> &str { + string.split("::").last().unwrap() +} + +#[cfg(test)] +mod name_formatting_tests { + use super::get_short_name; + + #[test] + fn trivial() { + assert_eq!(get_short_name("test_system"), "test_system") + } + + #[test] + fn path_seperated() { + assert_eq!( + get_short_name("bevy_prelude::make_fun_game"), + "make_fun_game".to_string() + ) + } + + #[test] + fn tuple_type() { + assert_eq!( + get_short_name("(String, String)"), + "(String, String)".to_string() + ) + } + + #[test] + fn array_type() { + assert_eq!(get_short_name("[i32; 3]"), "[i32; 3]".to_string()) + } + + #[test] + fn trivial_generics() { + assert_eq!(get_short_name("a"), "a".to_string()) + } + + #[test] + fn multiple_type_parameters() { + assert_eq!(get_short_name("a"), "a".to_string()) + } + + #[test] + fn generics() { + assert_eq!( + get_short_name("bevy_render::camera::camera::extract_cameras"), + "extract_cameras".to_string() + ) + } + + #[test] + fn nested_generics() { + assert_eq!( + get_short_name("bevy::mad_science::do_mad_science, bavy::TypeSystemAbuse>"), + "do_mad_science, TypeSystemAbuse>".to_string() + ) + } +} From d57a5880089dfbc4b42216a6a8c5e0cd2f4071b8 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sat, 2 Jul 2022 11:41:19 -0400 Subject: [PATCH 2/9] Use bevy_utils method in bevy_reflect --- crates/bevy_reflect/src/type_registry.rs | 71 +----------------------- 1 file changed, 1 insertion(+), 70 deletions(-) diff --git a/crates/bevy_reflect/src/type_registry.rs b/crates/bevy_reflect/src/type_registry.rs index f793ab6f8fca4..f1260cd7f940f 100644 --- a/crates/bevy_reflect/src/type_registry.rs +++ b/crates/bevy_reflect/src/type_registry.rs @@ -313,40 +313,7 @@ impl TypeRegistration { /// example, the short name of `alloc::vec::Vec>` /// would be `Vec>`. pub fn get_short_name(full_name: &str) -> String { - let mut short_name = String::new(); - - { - // A typename may be a composition of several other type names (e.g. generic parameters) - // separated by the characters that we try to find below. - // Then, each individual typename is shortened to its last path component. - // - // Note: Instead of `find`, `split_inclusive` would be nice but it's still unstable... - let mut remainder = full_name; - while let Some(index) = remainder.find(&['<', '>', '(', ')', '[', ']', ',', ';'][..]) { - let (path, new_remainder) = remainder.split_at(index); - // Push the shortened path in front of the found character - short_name.push_str(path.rsplit(':').next().unwrap()); - // Push the character that was found - let character = new_remainder.chars().next().unwrap(); - short_name.push(character); - // Advance the remainder - if character == ',' || character == ';' { - // A comma or semicolon is always followed by a space - short_name.push(' '); - remainder = &new_remainder[2..]; - } else { - remainder = &new_remainder[1..]; - } - } - - // The remainder will only be non-empty if there were no matches at all - if !remainder.is_empty() { - // Then, the full typename is a path that has to be shortened - short_name.push_str(remainder.rsplit(':').next().unwrap()); - } - } - - short_name + bevy_utils::get_short_name(full_name) } } @@ -459,42 +426,6 @@ mod test { use crate::TypeRegistration; use bevy_utils::HashMap; - #[test] - fn test_get_short_name() { - assert_eq!( - TypeRegistration::get_short_name(std::any::type_name::()), - "f64" - ); - assert_eq!( - TypeRegistration::get_short_name(std::any::type_name::()), - "String" - ); - assert_eq!( - TypeRegistration::get_short_name(std::any::type_name::<(u32, f64)>()), - "(u32, f64)" - ); - assert_eq!( - TypeRegistration::get_short_name(std::any::type_name::<(String, String)>()), - "(String, String)" - ); - assert_eq!( - TypeRegistration::get_short_name(std::any::type_name::<[f64]>()), - "[f64]" - ); - assert_eq!( - TypeRegistration::get_short_name(std::any::type_name::<[String]>()), - "[String]" - ); - assert_eq!( - TypeRegistration::get_short_name(std::any::type_name::<[f64; 16]>()), - "[f64; 16]" - ); - assert_eq!( - TypeRegistration::get_short_name(std::any::type_name::<[String; 16]>()), - "[String; 16]" - ); - } - #[test] fn test_property_type_registration() { assert_eq!( From 90a4d6f01c7bda9d97146540711e1b205d34e000 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sat, 2 Jul 2022 11:54:15 -0400 Subject: [PATCH 3/9] Remove TypeRegistry::get_short_name --- crates/bevy_reflect/src/type_registry.rs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/crates/bevy_reflect/src/type_registry.rs b/crates/bevy_reflect/src/type_registry.rs index f1260cd7f940f..97e84fef3a56f 100644 --- a/crates/bevy_reflect/src/type_registry.rs +++ b/crates/bevy_reflect/src/type_registry.rs @@ -231,7 +231,7 @@ impl TypeRegistryArc { /// a [`TypeData`] which can be used to downcast [`Reflect`] trait objects of /// this type to trait objects of the relevant trait. /// -/// [short name]: TypeRegistration::get_short_name +/// [short name]: bevy_utils::get_short_name /// [`TypeInfo`]: crate::TypeInfo /// [0]: crate::Reflect /// [1]: crate::Reflect @@ -287,14 +287,14 @@ impl TypeRegistration { let type_name = std::any::type_name::(); Self { data: HashMap::default(), - short_name: Self::get_short_name(type_name), + short_name: bevy_utils::get_short_name(type_name), type_info: T::type_info(), } } /// Returns the [short name] of the type. /// - /// [short name]: TypeRegistration::get_short_name + /// [short name]: bevy_utils::get_short_name pub fn short_name(&self) -> &str { &self.short_name } @@ -305,16 +305,6 @@ impl TypeRegistration { pub fn type_name(&self) -> &'static str { self.type_info.type_name() } - - /// Calculates the short name of a type. - /// - /// The short name of a type is its full name as returned by - /// [`std::any::type_name`], but with the prefix of all paths removed. For - /// example, the short name of `alloc::vec::Vec>` - /// would be `Vec>`. - pub fn get_short_name(full_name: &str) -> String { - bevy_utils::get_short_name(full_name) - } } impl Clone for TypeRegistration { From 129f66779dac30a47b52e0fea083f310748be348 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sat, 2 Jul 2022 11:54:28 -0400 Subject: [PATCH 4/9] Move detailed docs --- crates/bevy_utils/src/short_names.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/bevy_utils/src/short_names.rs b/crates/bevy_utils/src/short_names.rs index 25b2b5e71891a..09bbed0c2304a 100644 --- a/crates/bevy_utils/src/short_names.rs +++ b/crates/bevy_utils/src/short_names.rs @@ -1,4 +1,9 @@ /// Collapses a name returned by [`std::any::type_name`] to remove its module path +/// +/// The short name of a type is its full name as returned by +/// [`std::any::type_name`], but with the prefix of all paths removed. For +/// example, the short name of `alloc::vec::Vec>` +/// would be `Vec>`. pub fn get_short_name(full_name: &str) -> String { // Generics result in nested paths within <..> blocks // Consider "bevy_render::camera::camera::extract_cameras" From 8c3a80daf24926665678002d3db0f19f8879e233 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sat, 2 Jul 2022 11:57:42 -0400 Subject: [PATCH 5/9] Clippy --- crates/bevy_utils/src/short_names.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/bevy_utils/src/short_names.rs b/crates/bevy_utils/src/short_names.rs index 09bbed0c2304a..adf7f4a8641fa 100644 --- a/crates/bevy_utils/src/short_names.rs +++ b/crates/bevy_utils/src/short_names.rs @@ -58,7 +58,7 @@ mod name_formatting_tests { #[test] fn trivial() { - assert_eq!(get_short_name("test_system"), "test_system") + assert_eq!(get_short_name("test_system"), "test_system"); } #[test] @@ -66,7 +66,7 @@ mod name_formatting_tests { assert_eq!( get_short_name("bevy_prelude::make_fun_game"), "make_fun_game".to_string() - ) + ); } #[test] @@ -74,22 +74,22 @@ mod name_formatting_tests { assert_eq!( get_short_name("(String, String)"), "(String, String)".to_string() - ) + ); } #[test] fn array_type() { - assert_eq!(get_short_name("[i32; 3]"), "[i32; 3]".to_string()) + assert_eq!(get_short_name("[i32; 3]"), "[i32; 3]".to_string()); } #[test] fn trivial_generics() { - assert_eq!(get_short_name("a"), "a".to_string()) + assert_eq!(get_short_name("a"), "a".to_string()); } #[test] fn multiple_type_parameters() { - assert_eq!(get_short_name("a"), "a".to_string()) + assert_eq!(get_short_name("a"), "a".to_string()); } #[test] @@ -97,7 +97,7 @@ mod name_formatting_tests { assert_eq!( get_short_name("bevy_render::camera::camera::extract_cameras"), "extract_cameras".to_string() - ) + ); } #[test] @@ -105,6 +105,6 @@ mod name_formatting_tests { assert_eq!( get_short_name("bevy::mad_science::do_mad_science, bavy::TypeSystemAbuse>"), "do_mad_science, TypeSystemAbuse>".to_string() - ) + ); } } From 10aba097d46acfab86f2e60c0f41855bebb73774 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sat, 2 Jul 2022 12:09:03 -0400 Subject: [PATCH 6/9] Improve doc string summary --- crates/bevy_utils/src/short_names.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_utils/src/short_names.rs b/crates/bevy_utils/src/short_names.rs index adf7f4a8641fa..9aca625d6b27e 100644 --- a/crates/bevy_utils/src/short_names.rs +++ b/crates/bevy_utils/src/short_names.rs @@ -1,4 +1,4 @@ -/// Collapses a name returned by [`std::any::type_name`] to remove its module path +/// Shortens a type name to remove all module paths /// /// The short name of a type is its full name as returned by /// [`std::any::type_name`], but with the prefix of all paths removed. For From 911563ce20a611529841c036753ce20bf19245da Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sat, 2 Jul 2022 12:20:15 -0400 Subject: [PATCH 7/9] Migrate spancmp tool --- tools/spancmp/Cargo.toml | 2 +- tools/spancmp/src/pretty.rs | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/tools/spancmp/Cargo.toml b/tools/spancmp/Cargo.toml index 5b2b0c5749e92..c31bfc6e4c379 100644 --- a/tools/spancmp/Cargo.toml +++ b/tools/spancmp/Cargo.toml @@ -12,5 +12,5 @@ serde = { version = "1.0", features = ["derive"] } clap = { version = "3.2", features = ["derive"] } regex = "1.5" termcolor = "1.1" -bevy_reflect = { path = "../../crates/bevy_reflect", version = "0.8.0-dev" } +bevy_utils= { path = "../../crates/bevy_utils", version = "0.8.0-dev" } lazy_static = "1.4" diff --git a/tools/spancmp/src/pretty.rs b/tools/spancmp/src/pretty.rs index e51d453312ba8..730393a81c646 100644 --- a/tools/spancmp/src/pretty.rs +++ b/tools/spancmp/src/pretty.rs @@ -1,4 +1,4 @@ -use bevy_reflect::TypeRegistration; +use bevy_utils::get_short_name; use lazy_static::lazy_static; use regex::Regex; use termcolor::{Color, ColorSpec, StandardStream, WriteColor}; @@ -206,21 +206,18 @@ lazy_static! { pub fn simplify_name(name: &str) -> String { if let Some(captures) = SYSTEM_NAME.captures(name) { - return format!( - r#"system: name="{}""#, - TypeRegistration::get_short_name(&captures[1]) - ); + return format!(r#"system: name="{}""#, get_short_name(&captures[1])); } if let Some(captures) = SYSTEM_OVERHEAD.captures(name) { return format!( r#"system overhead: name="{}""#, - TypeRegistration::get_short_name(&captures[1]) + get_short_name(&captures[1]) ); } if let Some(captures) = SYSTEM_COMMANDS.captures(name) { return format!( r#"system_commands: name="{}""#, - TypeRegistration::get_short_name(&captures[1]) + get_short_name(&captures[1]) ); } name.to_string() From 81bd237a1610ee6e3cd8ed7d5dd52bf3eb8c9804 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sat, 2 Jul 2022 12:33:57 -0400 Subject: [PATCH 8/9] Formatting nit Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com> --- tools/spancmp/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/spancmp/Cargo.toml b/tools/spancmp/Cargo.toml index c31bfc6e4c379..aac07a306ef5a 100644 --- a/tools/spancmp/Cargo.toml +++ b/tools/spancmp/Cargo.toml @@ -12,5 +12,5 @@ serde = { version = "1.0", features = ["derive"] } clap = { version = "3.2", features = ["derive"] } regex = "1.5" termcolor = "1.1" -bevy_utils= { path = "../../crates/bevy_utils", version = "0.8.0-dev" } +bevy_utils = { path = "../../crates/bevy_utils", version = "0.8.0-dev" } lazy_static = "1.4" From 83ee3241b1138d10f3e521b77f761f914abb08d4 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sat, 2 Jul 2022 13:24:11 -0400 Subject: [PATCH 9/9] Manually lint for trailing periods ;) Co-authored-by: Federico Rinaldi --- crates/bevy_utils/src/short_names.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/bevy_utils/src/short_names.rs b/crates/bevy_utils/src/short_names.rs index 9aca625d6b27e..1c30bf61f9d0f 100644 --- a/crates/bevy_utils/src/short_names.rs +++ b/crates/bevy_utils/src/short_names.rs @@ -1,13 +1,13 @@ -/// Shortens a type name to remove all module paths +/// Shortens a type name to remove all module paths. /// /// The short name of a type is its full name as returned by /// [`std::any::type_name`], but with the prefix of all paths removed. For /// example, the short name of `alloc::vec::Vec>` /// would be `Vec>`. pub fn get_short_name(full_name: &str) -> String { - // Generics result in nested paths within <..> blocks - // Consider "bevy_render::camera::camera::extract_cameras" - // To tackle this, we parse the string from left to right, collapsing as we go + // Generics result in nested paths within <..> blocks. + // Consider "bevy_render::camera::camera::extract_cameras". + // To tackle this, we parse the string from left to right, collapsing as we go. let mut index: usize = 0; let end_of_string = full_name.len(); let mut parsed_name = String::new();