as_any/
lib.rs

1/*!
2This library provides some utility traits to make working with [`Any`] smoother.
3This crate contains similiar functionality to the `downcast` crate, but simpler,
4e.g. it isn't necessary to call some macro to instantiate the downcast methods.
5
6# Usage example
7```
8use as_any::{AsAny, Downcast};
9
10struct Test;
11
12trait Custom: AsAny {
13    // whatever you like to put inside of your trait
14}
15
16impl Custom for Test {}
17
18fn lol() {
19    let x = Test;
20    let y: &dyn Custom = &x;
21    // With (extension) trait `Downcast` in scope.
22    y.downcast_ref::<Test>().unwrap();
23}
24```
25**/
26
27#![no_std]
28#![forbid(unsafe_code)]
29use core::any::Any;
30
31/// This trait is an extension trait to [`Any`], and adds methods to retrieve a `&dyn Any`
32pub trait AsAny: Any {
33    fn as_any(&self) -> &dyn Any;
34    fn as_any_mut(&mut self) -> &mut dyn Any;
35
36    /// Gets the type name of `self`
37    fn type_name(&self) -> &'static str;
38}
39
40impl<T: Any> AsAny for T {
41    #[inline(always)]
42    fn as_any(&self) -> &dyn Any {
43        self
44    }
45
46    #[inline(always)]
47    fn as_any_mut(&mut self) -> &mut dyn Any {
48        self
49    }
50
51    #[inline(always)]
52    fn type_name(&self) -> &'static str {
53        core::any::type_name::<T>()
54    }
55}
56
57/// This is a shim around `AaAny` to avoid some boilerplate code.
58/// It is a separate trait because it is also implemented
59/// on runtime polymorphic traits (which are `!Sized`).
60pub trait Downcast: AsAny {
61    /// Returns `true` if the boxed type is the same as `T`.
62    ///
63    /// Forward to the method defined on the type `Any`.
64    #[inline]
65    fn is<T>(&self) -> bool
66    where
67        T: AsAny,
68    {
69        self.as_any().is::<T>()
70    }
71
72    /// Forward to the method defined on the type `Any`.
73    #[inline]
74    fn downcast_ref<T>(&self) -> Option<&T>
75    where
76        T: AsAny,
77    {
78        self.as_any().downcast_ref()
79    }
80
81    /// Forward to the method defined on the type `Any`.
82    #[inline]
83    fn downcast_mut<T>(&mut self) -> Option<&mut T>
84    where
85        T: AsAny,
86    {
87        self.as_any_mut().downcast_mut()
88    }
89}
90
91impl<T: ?Sized + AsAny> Downcast for T {}