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
/*!
This library provides some utility traits to make working with [`Any`] smoother.
This crate contains similiar functionality to the `downcast` crate, but simpler,
e.g. it isn't necessary to call some macro to instantiate the downcast methods.
# Usage example
```
use as_any::{AsAny, Downcast};
struct Test;
trait Custom: AsAny {
// whatever you like to put inside of your trait
}
impl Custom for Test {}
fn lol() {
let x = Test;
let y: &dyn Custom = &x;
// With (extension) trait `Downcast` in scope.
y.downcast_ref::<Test>().unwrap();
}
```
**/
#![no_std]
#![forbid(unsafe_code)]
use core::any::Any;
/// This trait is an extension trait to [`Any`], and adds methods to retrieve a `&dyn Any`
pub trait AsAny: Any {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
/// Gets the type name of `self`
fn type_name(&self) -> &'static str;
}
impl<T: Any> AsAny 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 type_name(&self) -> &'static str {
core::any::type_name::<T>()
}
}
/// This is a shim around `AaAny` to avoid some boilerplate code.
/// It is a separate trait because it is also implemented
/// on runtime polymorphic traits (which are `!Sized`).
pub trait Downcast: AsAny {
/// Returns `true` if the boxed type is the same as `T`.
///
/// Forward to the method defined on the type `Any`.
#[inline]
fn is<T>(&self) -> bool
where
T: AsAny,
{
self.as_any().is::<T>()
}
/// Forward to the method defined on the type `Any`.
#[inline]
fn downcast_ref<T>(&self) -> Option<&T>
where
T: AsAny,
{
self.as_any().downcast_ref()
}
/// Forward to the method defined on the type `Any`.
#[inline]
fn downcast_mut<T>(&mut self) -> Option<&mut T>
where
T: AsAny,
{
self.as_any_mut().downcast_mut()
}
}
impl<T: ?Sized + AsAny> Downcast for T {}