Add type alias support for plugin modules.
This commit is contained in:
@@ -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`].
|
||||
|
@@ -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"))]
|
||||
|
@@ -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(),
|
||||
|
@@ -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
43
src/types/custom_types.rs
Normal 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)
|
||||
}
|
||||
}
|
@@ -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};
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user