rhai/src/any.rs

104 lines
2.1 KiB
Rust
Raw Normal View History

2019-09-30 19:57:21 +02:00
use std::any::{type_name, Any as StdAny, TypeId};
2017-12-20 12:16:14 +01:00
use std::fmt;
pub trait Any: StdAny {
fn type_id(&self) -> TypeId;
2019-09-30 19:57:21 +02:00
fn type_name(&self) -> String;
2019-09-18 12:21:07 +02:00
fn box_clone(&self) -> Box<dyn Any>;
2017-12-20 12:16:14 +01:00
/// This type may only be implemented by `rhai`.
#[doc(hidden)]
fn _closed(&self) -> _Private;
}
impl<T> Any for T
2019-09-18 12:21:07 +02:00
where
T: Clone + StdAny + ?Sized,
2017-12-20 12:16:14 +01:00
{
#[inline]
fn type_id(&self) -> TypeId {
TypeId::of::<T>()
}
2019-09-30 19:57:21 +02:00
fn type_name(&self) -> String {
type_name::<T>().to_string()
}
2017-12-20 12:16:14 +01:00
#[inline]
2019-09-18 12:21:07 +02:00
fn box_clone(&self) -> Box<dyn Any> {
2017-12-20 12:16:14 +01:00
Box::new(self.clone())
}
2019-09-18 12:21:07 +02:00
fn _closed(&self) -> _Private {
_Private
2017-12-20 12:16:14 +01:00
}
2019-09-18 12:21:07 +02:00
}
2017-12-20 12:16:14 +01:00
2019-09-18 12:21:07 +02:00
impl dyn Any {
//#[inline]
// fn box_clone(&self) -> Box<dyn Any> {
// Any::box_clone(self)
// }
2017-12-20 12:16:14 +01:00
#[inline]
pub fn is<T: Any>(&self) -> bool {
let t = TypeId::of::<T>();
2019-09-18 12:21:07 +02:00
let boxed = <dyn Any as Any>::type_id(self);
2017-12-20 12:16:14 +01:00
t == boxed
}
#[inline]
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
if self.is::<T>() {
2019-09-18 12:21:07 +02:00
unsafe { Some(&*(self as *const dyn Any as *const T)) }
2017-12-20 12:16:14 +01:00
} else {
None
}
}
#[inline]
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
if self.is::<T>() {
2019-09-18 12:21:07 +02:00
unsafe { Some(&mut *(self as *mut dyn Any as *mut T)) }
2017-12-20 12:16:14 +01:00
} else {
None
}
}
}
2019-09-18 12:21:07 +02:00
impl Clone for Box<dyn Any> {
2017-12-20 12:16:14 +01:00
fn clone(&self) -> Self {
2019-09-18 12:21:07 +02:00
Any::box_clone(self.as_ref() as &dyn Any)
2017-12-20 12:16:14 +01:00
}
}
2019-09-18 12:21:07 +02:00
impl fmt::Debug for dyn Any {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad("?")
2017-12-20 12:16:14 +01:00
}
}
pub trait AnyExt: Sized {
fn downcast<T: Any + Clone>(self) -> Result<Box<T>, Self>;
}
2019-09-18 12:21:07 +02:00
impl AnyExt for Box<dyn Any> {
2017-12-20 12:16:14 +01:00
fn downcast<T: Any + Clone>(self) -> Result<Box<T>, Self> {
if self.is::<T>() {
unsafe {
2019-09-18 12:21:07 +02:00
let raw: *mut dyn Any = Box::into_raw(self);
2017-12-20 12:16:14 +01:00
Ok(Box::from_raw(raw as *mut T))
}
} else {
Err(self)
}
}
}
/// Private type which ensures that `rhai::Any` can only
/// be implemented by this crate.
#[doc(hidden)]
pub struct _Private;