Move Variant into separate file.

This commit is contained in:
Stephen Chung 2022-09-26 12:19:45 +08:00
parent 7d87a59315
commit 335d12e182
4 changed files with 111 additions and 102 deletions

View File

@ -169,6 +169,7 @@ impl Engine {
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
/// // Register a token mapper. /// // Register a token mapper.
/// # #[allow(deprecated)]
/// engine.on_parse_token(|token, _, _| { /// engine.on_parse_token(|token, _, _| {
/// match token { /// match token {
/// // Convert all integer literals to strings /// // Convert all integer literals to strings

View File

@ -1,7 +1,5 @@
//! Helper module which defines the [`Dynamic`] data type and the //! Helper module which defines the [`Dynamic`] data type.
//! [`Any`] trait to to allow custom type handling.
use crate::func::SendSync;
use crate::{reify, ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, INT}; use crate::{reify, ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, INT};
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
@ -14,6 +12,8 @@ use std::{
str::FromStr, str::FromStr,
}; };
pub use super::Variant;
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(target_family = "wasm"))] #[cfg(not(target_family = "wasm"))]
pub use std::time::Instant; pub use std::time::Instant;
@ -26,105 +26,6 @@ pub use instant::Instant;
#[allow(dead_code)] #[allow(dead_code)]
const CHECKED: &str = "data type was checked"; 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<T: Any + Clone + SendSync> 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<dyn Any>`][Any].
#[must_use]
fn as_boxed_any(self: Box<Self>) -> Box<dyn Any>;
/// 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<dyn Variant>;
}
/// _(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<dyn Any>`][Any].
#[must_use]
fn as_boxed_any(self: Box<Self>) -> Box<dyn Any>;
/// 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<dyn Variant>;
}
impl<T: Any + Clone + SendSync> 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<Self>) -> Box<dyn Any> {
self
}
#[inline(always)]
fn type_name(&self) -> &'static str {
type_name::<T>()
}
#[inline(always)]
fn clone_object(&self) -> Box<dyn Variant> {
Box::new(self.clone()) as Box<dyn Variant>
}
}
impl dyn Variant {
/// Is this [`Variant`] a specific type?
#[inline(always)]
#[must_use]
pub fn is<T: Any>(&self) -> bool {
TypeId::of::<T>() == self.type_id()
}
}
/// _(internals)_ Modes of access. /// _(internals)_ Modes of access.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)]

View File

@ -9,6 +9,7 @@ pub mod immutable_string;
pub mod interner; pub mod interner;
pub mod parse_error; pub mod parse_error;
pub mod scope; pub mod scope;
pub mod variant;
pub use bloom_filter::BloomFilterU64; pub use bloom_filter::BloomFilterU64;
pub use custom_types::{CustomTypeInfo, CustomTypesCollection}; pub use custom_types::{CustomTypeInfo, CustomTypesCollection};
@ -21,3 +22,4 @@ pub use immutable_string::ImmutableString;
pub use interner::StringsInterner; pub use interner::StringsInterner;
pub use parse_error::{LexError, ParseError, ParseErrorType}; pub use parse_error::{LexError, ParseError, ParseErrorType};
pub use scope::Scope; pub use scope::Scope;
pub use variant::Variant;

105
src/types/variant.rs Normal file
View File

@ -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<T: Any + Clone + SendSync> 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<dyn Any>`][Any].
#[must_use]
fn as_boxed_any(self: Box<Self>) -> Box<dyn Any>;
/// 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<dyn Variant>;
}
/// _(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<dyn Any>`][Any].
#[must_use]
fn as_boxed_any(self: Box<Self>) -> Box<dyn Any>;
/// 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<dyn Variant>;
}
impl<T: Any + Clone + SendSync> 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<Self>) -> Box<dyn Any> {
self
}
#[inline(always)]
fn type_name(&self) -> &'static str {
type_name::<T>()
}
#[inline(always)]
fn clone_object(&self) -> Box<dyn Variant> {
Box::new(self.clone()) as Box<dyn Variant>
}
}
impl dyn Variant {
/// Is this [`Variant`] a specific type?
#[inline(always)]
#[must_use]
pub fn is<T: Any>(&self) -> bool {
TypeId::of::<T>() == self.type_id()
}
}