diff --git a/src/api/events.rs b/src/api/events.rs index 42511be3..a44ee2a4 100644 --- a/src/api/events.rs +++ b/src/api/events.rs @@ -169,6 +169,7 @@ impl Engine { /// let mut engine = Engine::new(); /// /// // Register a token mapper. + /// # #[allow(deprecated)] /// engine.on_parse_token(|token, _, _| { /// match token { /// // Convert all integer literals to strings diff --git a/src/types/dynamic.rs b/src/types/dynamic.rs index b310b302..c1fe1dcf 100644 --- a/src/types/dynamic.rs +++ b/src/types/dynamic.rs @@ -1,7 +1,5 @@ -//! Helper module which defines the [`Dynamic`] data type and the -//! [`Any`] trait to to allow custom type handling. +//! Helper module which defines the [`Dynamic`] data type. -use crate::func::SendSync; use crate::{reify, ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, INT}; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -14,6 +12,8 @@ use std::{ str::FromStr, }; +pub use super::Variant; + #[cfg(not(feature = "no_std"))] #[cfg(not(target_family = "wasm"))] pub use std::time::Instant; @@ -26,105 +26,6 @@ pub use instant::Instant; #[allow(dead_code)] const CHECKED: &str = "data type was checked"; -mod private { - use crate::func::SendSync; - use std::any::Any; - - /// A sealed trait that prevents other crates from implementing [`Variant`][super::Variant]. - pub trait Sealed {} - - impl Sealed for T {} -} - -/// _(internals)_ Trait to represent any type. -/// Exported under the `internals` feature only. -/// -/// This trait is sealed and cannot be implemented. -/// -/// Currently, [`Variant`] is not [`Send`] nor [`Sync`], so it can practically be any type. -/// Turn on the `sync` feature to restrict it to only types that implement [`Send`] `+` [`Sync`]. -#[cfg(not(feature = "sync"))] -pub trait Variant: Any + private::Sealed { - /// Convert this [`Variant`] trait object to [`&dyn Any`][Any]. - #[must_use] - fn as_any(&self) -> &dyn Any; - - /// Convert this [`Variant`] trait object to [`&mut dyn Any`][Any]. - #[must_use] - fn as_any_mut(&mut self) -> &mut dyn Any; - - /// Convert this [`Variant`] trait object to [`Box`][Any]. - #[must_use] - fn as_boxed_any(self: Box) -> Box; - - /// Get the name of this type. - #[must_use] - fn type_name(&self) -> &'static str; - - /// Clone this [`Variant`] trait object. - #[must_use] - fn clone_object(&self) -> Box; -} - -/// _(internals)_ Trait to represent any type. -/// Exported under the `internals` feature only. -/// -/// This trait is sealed and cannot be implemented. -#[cfg(feature = "sync")] -pub trait Variant: Any + Send + Sync + private::Sealed { - /// Convert this [`Variant`] trait object to [`&dyn Any`][Any]. - #[must_use] - fn as_any(&self) -> &dyn Any; - - /// Convert this [`Variant`] trait object to [`&mut dyn Any`][Any]. - #[must_use] - fn as_any_mut(&mut self) -> &mut dyn Any; - - /// Convert this [`Variant`] trait object to [`Box`][Any]. - #[must_use] - fn as_boxed_any(self: Box) -> Box; - - /// Get the name of this type. - #[must_use] - fn type_name(&self) -> &'static str; - - /// Clone this [`Variant`] trait object. - #[must_use] - fn clone_object(&self) -> Box; -} - -impl Variant for T { - #[inline(always)] - fn as_any(&self) -> &dyn Any { - self - } - #[inline(always)] - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } - #[inline(always)] - fn as_boxed_any(self: Box) -> Box { - self - } - #[inline(always)] - fn type_name(&self) -> &'static str { - type_name::() - } - #[inline(always)] - fn clone_object(&self) -> Box { - Box::new(self.clone()) as Box - } -} - -impl dyn Variant { - /// Is this [`Variant`] a specific type? - #[inline(always)] - #[must_use] - pub fn is(&self) -> bool { - TypeId::of::() == self.type_id() - } -} - /// _(internals)_ Modes of access. /// Exported under the `internals` feature only. #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] diff --git a/src/types/mod.rs b/src/types/mod.rs index 347bc85c..475ca2c9 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -9,6 +9,7 @@ pub mod immutable_string; pub mod interner; pub mod parse_error; pub mod scope; +pub mod variant; pub use bloom_filter::BloomFilterU64; pub use custom_types::{CustomTypeInfo, CustomTypesCollection}; @@ -21,3 +22,4 @@ pub use immutable_string::ImmutableString; pub use interner::StringsInterner; pub use parse_error::{LexError, ParseError, ParseErrorType}; pub use scope::Scope; +pub use variant::Variant; diff --git a/src/types/variant.rs b/src/types/variant.rs new file mode 100644 index 00000000..0e1d4e6c --- /dev/null +++ b/src/types/variant.rs @@ -0,0 +1,105 @@ +//! [`Variant`] trait to to allow custom type handling. + +use crate::func::SendSync; +use std::any::{type_name, Any, TypeId}; +#[cfg(feature = "no_std")] +use std::prelude::v1::*; + +mod private { + use crate::func::SendSync; + use std::any::Any; + + /// A sealed trait that prevents other crates from implementing [`Variant`][super::Variant]. + pub trait Sealed {} + + impl Sealed for T {} +} + +/// _(internals)_ Trait to represent any type. +/// Exported under the `internals` feature only. +/// +/// This trait is sealed and cannot be implemented. +/// +/// Currently, [`Variant`] is not [`Send`] nor [`Sync`], so it can practically be any type. +/// Turn on the `sync` feature to restrict it to only types that implement [`Send`] `+` [`Sync`]. +#[cfg(not(feature = "sync"))] +pub trait Variant: Any + private::Sealed { + /// Convert this [`Variant`] trait object to [`&dyn Any`][Any]. + #[must_use] + fn as_any(&self) -> &dyn Any; + + /// Convert this [`Variant`] trait object to [`&mut dyn Any`][Any]. + #[must_use] + fn as_any_mut(&mut self) -> &mut dyn Any; + + /// Convert this [`Variant`] trait object to [`Box`][Any]. + #[must_use] + fn as_boxed_any(self: Box) -> Box; + + /// Get the name of this type. + #[must_use] + fn type_name(&self) -> &'static str; + + /// Clone this [`Variant`] trait object. + #[must_use] + fn clone_object(&self) -> Box; +} + +/// _(internals)_ Trait to represent any type. +/// Exported under the `internals` feature only. +/// +/// This trait is sealed and cannot be implemented. +#[cfg(feature = "sync")] +pub trait Variant: Any + Send + Sync + private::Sealed { + /// Convert this [`Variant`] trait object to [`&dyn Any`][Any]. + #[must_use] + fn as_any(&self) -> &dyn Any; + + /// Convert this [`Variant`] trait object to [`&mut dyn Any`][Any]. + #[must_use] + fn as_any_mut(&mut self) -> &mut dyn Any; + + /// Convert this [`Variant`] trait object to [`Box`][Any]. + #[must_use] + fn as_boxed_any(self: Box) -> Box; + + /// Get the name of this type. + #[must_use] + fn type_name(&self) -> &'static str; + + /// Clone this [`Variant`] trait object. + #[must_use] + fn clone_object(&self) -> Box; +} + +impl Variant for T { + #[inline(always)] + fn as_any(&self) -> &dyn Any { + self + } + #[inline(always)] + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + #[inline(always)] + fn as_boxed_any(self: Box) -> Box { + self + } + #[inline(always)] + fn type_name(&self) -> &'static str { + type_name::() + } + #[inline(always)] + fn clone_object(&self) -> Box { + Box::new(self.clone()) as Box + } +} + +impl dyn Variant { + /// Is this [`Variant`] a specific type? + #[inline(always)] + #[must_use] + pub fn is(&self) -> bool { + TypeId::of::() == self.type_id() + } +}