diff --git a/CHANGELOG.md b/CHANGELOG.md index e94439f0..b5f152ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Enhancements * `starts_with` and `ends_with` are added for strings. * Variables in modules registered via `register_global_module` can now be accessed in the global namespace. * `Dynamic::into_read_only` is added to convert a `Dynamic` value into constant. +* `Module` now holds a collection of custom types with an API. Version 1.5.0 diff --git a/src/api/register.rs b/src/api/register.rs index 1d5220d5..8d69f7d6 100644 --- a/src/api/register.rs +++ b/src/api/register.rs @@ -273,7 +273,7 @@ impl Engine { /// ``` #[inline(always)] pub fn register_type_with_name(&mut self, name: &str) -> &mut Self { - self.custom_types.add_type::(name); + self.global_namespace_mut().set_custom_type::(name); self } /// Register a custom type for use with the [`Engine`], with a pretty-print name @@ -289,7 +289,8 @@ impl Engine { name: impl Into, ) -> &mut Self { // Add the pretty-print type name into the map - self.custom_types.add(fully_qualified_type_path, name); + self.global_namespace_mut() + .set_custom_type_raw(fully_qualified_type_path, name); self } /// Register an type iterator for an iterable type with the [`Engine`]. diff --git a/src/api/type_names.rs b/src/api/type_names.rs index 9c4ca5ea..0b36603e 100644 --- a/src/api/type_names.rs +++ b/src/api/type_names.rs @@ -97,7 +97,6 @@ impl Engine { #[cfg(feature = "no_module")] return None; }) - .or_else(|| self.custom_types.get(name)) .unwrap_or_else(|| map_std_type_name(name, true)) } @@ -119,8 +118,18 @@ impl Engine { }; } - self.custom_types - .get(name) + self.global_modules + .iter() + .find_map(|m| m.get_custom_type(name)) + .or_else(|| { + #[cfg(not(feature = "no_module"))] + return self + .global_sub_modules + .iter() + .find_map(|(_, m)| m.get_custom_type(name)); + #[cfg(feature = "no_module")] + return None; + }) .unwrap_or_else(|| match name { "INT" => return type_name::(), #[cfg(not(feature = "no_float"))] diff --git a/src/engine.rs b/src/engine.rs index 76577c7d..6b7614af 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -7,7 +7,7 @@ use crate::func::native::{ }; use crate::packages::{Package, StandardPackage}; use crate::tokenizer::Token; -use crate::types::{dynamic::Union, CustomTypesCollection}; +use crate::types::dynamic::Union; use crate::{ Dynamic, Identifier, ImmutableString, Module, OptimizationLevel, Position, RhaiResult, Shared, StaticVec, @@ -105,9 +105,6 @@ pub struct Engine { #[cfg(not(feature = "no_module"))] pub(crate) module_resolver: Box, - /// A map mapping type names to pretty-print names. - pub(crate) custom_types: CustomTypesCollection, - /// An empty [`ImmutableString`] for cloning purposes. pub(crate) empty_string: ImmutableString, @@ -160,8 +157,7 @@ impl fmt::Debug for Engine { #[cfg(not(feature = "no_module"))] f.field("global_sub_modules", &self.global_sub_modules); - f.field("type_names", &self.custom_types) - .field("disabled_symbols", &self.disabled_symbols) + f.field("disabled_symbols", &self.disabled_symbols) .field("custom_keywords", &self.custom_keywords) .field("custom_syntax", &(!self.custom_syntax.is_empty())) .field("def_var_filter", &self.def_var_filter.is_some()) @@ -263,7 +259,6 @@ impl Engine { #[cfg(not(feature = "no_module"))] module_resolver: Box::new(crate::module::resolvers::DummyModuleResolver::new()), - custom_types: CustomTypesCollection::new(), empty_string: ImmutableString::new(), disabled_symbols: BTreeSet::new(), custom_keywords: BTreeMap::new(), diff --git a/src/module/mod.rs b/src/module/mod.rs index a70ee8e9..34c2887b 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -421,6 +421,15 @@ impl Module { pub fn set_custom_type(&mut self, name: &str) { self.custom_types.add_type::(name) } + /// Map a custom type to a friendly display name. + #[inline(always)] + pub fn set_custom_type_raw( + &mut self, + type_name: impl Into, + name: impl Into, + ) { + self.custom_types.add(type_name, name) + } /// Get the display name of a registered custom type. #[inline(always)] pub fn get_custom_type(&self, key: &str) -> Option<&str> { diff --git a/src/types/custom_types.rs b/src/types/custom_types.rs index e46aaddc..34759d1f 100644 --- a/src/types/custom_types.rs +++ b/src/types/custom_types.rs @@ -27,13 +27,18 @@ impl CustomTypesCollection { } /// Register a custom type. #[inline(always)] - pub fn add(&mut self, key: impl Into, name: impl Into) { - self.0.insert(key.into(), name.into()); + pub fn add(&mut self, type_name: impl Into, name: impl Into) { + self.add_raw(type_name, name.into()); } /// Register a custom type. #[inline(always)] pub fn add_type(&mut self, name: &str) { - self.0.insert(type_name::().into(), name.into()); + self.add_raw(type_name::(), name.into()); + } + /// Register a custom type. + #[inline(always)] + pub fn add_raw(&mut self, type_name: impl Into, custom_type: CustomType) { + self.0.insert(type_name.into(), custom_type); } /// Find a custom type. #[inline(always)]