rhai/types/
variant.rs

1//! [`Variant`] trait to to allow custom type handling.
2
3use crate::func::SendSync;
4use std::any::{type_name, Any, TypeId};
5#[cfg(feature = "no_std")]
6use std::prelude::v1::*;
7
8mod private {
9    use crate::func::SendSync;
10    use std::any::Any;
11
12    /// A sealed trait that prevents other crates from implementing [`Variant`][super::Variant].
13    pub trait Sealed {}
14
15    impl<T: Any + Clone + SendSync> Sealed for T {}
16}
17
18/// _(internals)_ Trait to represent any type.
19/// Exported under the `internals` feature only.
20///
21/// This trait is sealed and cannot be implemented.
22///
23/// Currently, [`Variant`] is not [`Send`] nor [`Sync`], so it can practically be any type.
24/// Turn on the `sync` feature to restrict it to only types that implement [`Send`] `+` [`Sync`].
25#[cfg(not(feature = "sync"))]
26pub trait Variant: Any + private::Sealed {
27    /// Convert this [`Variant`] trait object to [`&dyn Any`][Any].
28    #[must_use]
29    fn as_any(&self) -> &dyn Any;
30
31    /// Convert this [`Variant`] trait object to [`&mut dyn Any`][Any].
32    #[must_use]
33    fn as_any_mut(&mut self) -> &mut dyn Any;
34
35    /// Convert this [`Variant`] trait object to [`Box<dyn Any>`][Any].
36    #[must_use]
37    fn as_boxed_any(self: Box<Self>) -> Box<dyn Any>;
38
39    /// Get the name of this type.
40    #[must_use]
41    fn type_name(&self) -> &'static str;
42
43    /// Clone this [`Variant`] trait object.
44    #[must_use]
45    fn clone_object(&self) -> Box<dyn Variant>;
46}
47
48/// _(internals)_ Trait to represent any type.
49/// Exported under the `internals` feature only.
50///
51/// This trait is sealed and cannot be implemented.
52#[cfg(feature = "sync")]
53pub trait Variant: Any + Send + Sync + private::Sealed {
54    /// Convert this [`Variant`] trait object to [`&dyn Any`][Any].
55    #[must_use]
56    fn as_any(&self) -> &dyn Any;
57
58    /// Convert this [`Variant`] trait object to [`&mut dyn Any`][Any].
59    #[must_use]
60    fn as_any_mut(&mut self) -> &mut dyn Any;
61
62    /// Convert this [`Variant`] trait object to [`Box<dyn Any>`][Any].
63    #[must_use]
64    fn as_boxed_any(self: Box<Self>) -> Box<dyn Any>;
65
66    /// Get the name of this type.
67    #[must_use]
68    fn type_name(&self) -> &'static str;
69
70    /// Clone this [`Variant`] trait object.
71    #[must_use]
72    fn clone_object(&self) -> Box<dyn Variant>;
73}
74
75impl<T: Any + Clone + SendSync> Variant for T {
76    #[inline(always)]
77    fn as_any(&self) -> &dyn Any {
78        self
79    }
80    #[inline(always)]
81    fn as_any_mut(&mut self) -> &mut dyn Any {
82        self
83    }
84    #[inline(always)]
85    fn as_boxed_any(self: Box<Self>) -> Box<dyn Any> {
86        self
87    }
88    #[inline(always)]
89    fn type_name(&self) -> &'static str {
90        type_name::<T>()
91    }
92    #[inline(always)]
93    fn clone_object(&self) -> Box<dyn Variant> {
94        Box::new(self.clone()) as Box<dyn Variant>
95    }
96}
97
98impl dyn Variant {
99    /// Is this [`Variant`] a specific type?
100    #[inline(always)]
101    #[must_use]
102    pub fn is<T: Any>(&self) -> bool {
103        TypeId::of::<T>() == self.type_id()
104    }
105}