1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 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()
}
}