Add type alias support for plugin modules.

This commit is contained in:
Stephen Chung
2022-03-19 09:43:18 +08:00
parent 6546eae95f
commit fefa633cf0
12 changed files with 207 additions and 18 deletions

View File

@@ -10,7 +10,7 @@ use std::any::{type_name, TypeId};
use std::prelude::v1::*;
impl Engine {
/// Get the global namespace module (which is the last module in `global_modules`).
/// Get the global namespace module (which is the fist module in `global_modules`).
#[inline(always)]
#[allow(dead_code)]
pub(crate) fn global_namespace(&self) -> &Module {
@@ -273,7 +273,8 @@ impl Engine {
/// ```
#[inline(always)]
pub fn register_type_with_name<T: Variant + Clone>(&mut self, name: &str) -> &mut Self {
self.register_type_with_name_raw(type_name::<T>(), name)
self.custom_types.add_type::<T>(name);
self
}
/// Register a custom type for use with the [`Engine`], with a pretty-print name
/// for the `type_of` function. The type must implement [`Clone`].
@@ -288,8 +289,7 @@ impl Engine {
name: impl Into<Identifier>,
) -> &mut Self {
// Add the pretty-print type name into the map
self.type_names
.insert(fully_qualified_type_path.into(), name.into());
self.custom_types.add(fully_qualified_type_path, name);
self
}
/// Register an type iterator for an iterable type with the [`Engine`].

View File

@@ -85,9 +85,15 @@ impl Engine {
#[inline]
#[must_use]
pub fn map_type_name<'a>(&'a self, name: &'a str) -> &'a str {
self.type_names
.get(name)
.map(|s| s.as_str())
self.global_modules
.iter()
.find_map(|m| m.get_custom_type(name))
.or_else(|| {
self.global_sub_modules
.iter()
.find_map(|(_, m)| m.get_custom_type(name))
})
.or_else(|| self.custom_types.get(name))
.unwrap_or_else(|| map_std_type_name(name, true))
}
@@ -109,9 +115,8 @@ impl Engine {
};
}
self.type_names
self.custom_types
.get(name)
.map(|s| s.as_str())
.unwrap_or_else(|| match name {
"INT" => return type_name::<crate::INT>(),
#[cfg(not(feature = "no_float"))]

View File

@@ -6,7 +6,7 @@ use crate::func::native::{
};
use crate::packages::{Package, StandardPackage};
use crate::tokenizer::Token;
use crate::types::dynamic::Union;
use crate::types::{dynamic::Union, CustomTypesCollection};
use crate::{
Dynamic, Identifier, ImmutableString, Module, OptimizationLevel, Position, RhaiResult, Shared,
StaticVec,
@@ -105,7 +105,7 @@ pub struct Engine {
pub(crate) module_resolver: Option<Box<dyn crate::ModuleResolver>>,
/// A map mapping type names to pretty-print names.
pub(crate) type_names: BTreeMap<Identifier, Identifier>,
pub(crate) custom_types: CustomTypesCollection,
/// An empty [`ImmutableString`] for cloning purposes.
pub(crate) empty_string: ImmutableString,
@@ -160,7 +160,7 @@ impl fmt::Debug for Engine {
f.field("global_sub_modules", &self.global_sub_modules)
.field("module_resolver", &self.module_resolver.is_some());
f.field("type_names", &self.type_names)
f.field("type_names", &self.custom_types)
.field("disabled_symbols", &self.disabled_symbols)
.field("custom_keywords", &self.custom_keywords)
.field("custom_syntax", &(!self.custom_syntax.is_empty()))
@@ -271,7 +271,7 @@ impl Engine {
#[cfg(not(feature = "no_module"))]
module_resolver: None,
type_names: BTreeMap::new(),
custom_types: CustomTypesCollection::new(),
empty_string: ImmutableString::new(),
disabled_symbols: BTreeSet::new(),
custom_keywords: BTreeMap::new(),

View File

@@ -5,7 +5,7 @@ use crate::func::{
shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, RegisterNativeFunction,
SendSync,
};
use crate::types::dynamic::Variant;
use crate::types::{dynamic::Variant, CustomTypesCollection};
use crate::{
calc_fn_params_hash, calc_qualified_fn_hash, combine_hashes, Dynamic, Identifier,
ImmutableString, NativeCallContext, RhaiResultOf, Shared, StaticVec,
@@ -232,6 +232,8 @@ pub struct Module {
pub(crate) internal: bool,
/// Is this module part of a standard library?
pub(crate) standard: bool,
/// Custom types.
custom_types: CustomTypesCollection,
/// Sub-modules.
modules: BTreeMap<Identifier, Shared<Module>>,
/// [`Module`] variables.
@@ -339,6 +341,7 @@ impl Module {
id: Identifier::new_const(),
internal: false,
standard: false,
custom_types: CustomTypesCollection::new(),
modules: BTreeMap::new(),
variables: BTreeMap::new(),
all_variables: BTreeMap::new(),
@@ -413,6 +416,17 @@ impl Module {
self
}
/// Map a custom type to a friendly display name.
#[inline(always)]
pub fn set_custom_type<T>(&mut self, name: &str) {
self.custom_types.add_type::<T>(name)
}
/// Get the display name of a registered custom type.
#[inline(always)]
pub fn get_custom_type(&self, key: &str) -> Option<&str> {
self.custom_types.get(key)
}
/// Is the [`Module`] empty?
///
/// # Example

43
src/types/custom_types.rs Normal file
View File

@@ -0,0 +1,43 @@
//! Collection of custom types.
use crate::Identifier;
use std::{any::type_name, collections::BTreeMap, fmt};
/// _(internals)_ A custom type.
/// Exported under the `internals` feature only.
pub type CustomType = Identifier;
/// _(internals)_ A collection of custom types.
/// Exported under the `internals` feature only.
#[derive(Clone, Hash, Default)]
pub struct CustomTypesCollection(BTreeMap<Identifier, CustomType>);
impl fmt::Debug for CustomTypesCollection {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("CustomTypesCollection ")?;
f.debug_map().entries(self.0.iter()).finish()
}
}
impl CustomTypesCollection {
/// Create a new [`CustomTypesCollection`].
#[inline(always)]
pub fn new() -> Self {
Self(BTreeMap::new())
}
/// Register a custom type.
#[inline(always)]
pub fn add(&mut self, key: impl Into<Identifier>, name: impl Into<Identifier>) {
self.0.insert(key.into(), name.into());
}
/// Register a custom type.
#[inline(always)]
pub fn add_type<T>(&mut self, name: &str) {
self.0.insert(type_name::<T>().into(), name.into());
}
/// Find a custom type.
#[inline(always)]
pub fn get(&self, key: &str) -> Option<&str> {
self.0.get(key).map(CustomType::as_str)
}
}

View File

@@ -1,4 +1,5 @@
//! Helper module which defines the [`Any`] trait to to allow dynamic value handling.
//! Helper module which defines the [`Dynamic`] data type and the
//! [`Any`] trait to to allow custom type handling.
use crate::func::native::SendSync;
use crate::{reify, ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, INT};

View File

@@ -1,5 +1,6 @@
//! Module defining Rhai data types.
pub mod custom_types;
pub mod dynamic;
pub mod error;
pub mod fn_ptr;
@@ -8,6 +9,7 @@ pub mod interner;
pub mod parse_error;
pub mod scope;
pub use custom_types::{CustomType, CustomTypesCollection};
pub use dynamic::Dynamic;
#[cfg(not(feature = "no_std"))]
pub use dynamic::Instant;