xref: /DragonOS/kernel/crates/intertrait/src/lib.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
1*bd70d2d1SLoGin //! A library providing direct casting among trait objects implemented by a type.
2*bd70d2d1SLoGin //!
3*bd70d2d1SLoGin //! In Rust, an object of a sub-trait of [`Any`] can be downcast to a concrete type
4*bd70d2d1SLoGin //! at runtime if the type is known. But no direct casting between two trait objects
5*bd70d2d1SLoGin //! (i.e. without involving the concrete type of the backing value) is possible
6*bd70d2d1SLoGin //! (even no coercion from a trait object to that of its super-trait yet).
7*bd70d2d1SLoGin //!
8*bd70d2d1SLoGin //! With this crate, any trait object with [`CastFrom`] as its super-trait can be cast directly
9*bd70d2d1SLoGin //! to another trait object implemented by the underlying type if the target traits are
10*bd70d2d1SLoGin //! registered beforehand with the macros provided by this crate.
11*bd70d2d1SLoGin //!
12*bd70d2d1SLoGin //! # Usage
13*bd70d2d1SLoGin //! ```
14*bd70d2d1SLoGin //! use intertrait::*;
15*bd70d2d1SLoGin //! use intertrait::cast::*;
16*bd70d2d1SLoGin //!
17*bd70d2d1SLoGin //! struct Data;
18*bd70d2d1SLoGin //!
19*bd70d2d1SLoGin //! trait Source: CastFrom {}
20*bd70d2d1SLoGin //!
21*bd70d2d1SLoGin //! trait Greet {
22*bd70d2d1SLoGin //!     fn greet(&self);
23*bd70d2d1SLoGin //! }
24*bd70d2d1SLoGin //!
25*bd70d2d1SLoGin //! #[cast_to]
26*bd70d2d1SLoGin //! impl Greet for Data {
27*bd70d2d1SLoGin //!     fn greet(&self) {
28*bd70d2d1SLoGin //!         println!("Hello");
29*bd70d2d1SLoGin //!     }
30*bd70d2d1SLoGin //! }
31*bd70d2d1SLoGin //!
32*bd70d2d1SLoGin //! impl Source for Data {}
33*bd70d2d1SLoGin //!
34*bd70d2d1SLoGin //! let data = Data;
35*bd70d2d1SLoGin //! let source: &dyn Source = &data;
36*bd70d2d1SLoGin //! let greet = source.cast::<dyn Greet>();
37*bd70d2d1SLoGin //! greet.unwrap().greet();
38*bd70d2d1SLoGin //! ```
39*bd70d2d1SLoGin //!
40*bd70d2d1SLoGin //! Target traits must be explicitly designated beforehand. There are three ways to do it:
41*bd70d2d1SLoGin //!
42*bd70d2d1SLoGin //! * [`#[cast_to]`][cast_to] to `impl` item
43*bd70d2d1SLoGin //! * [`#[cast_to(Trait)]`][cast_to] to type definition
44*bd70d2d1SLoGin //! * [`castable_to!(Type => Trait1, Trait2)`][castable_to]
45*bd70d2d1SLoGin //!
46*bd70d2d1SLoGin //! If the underlying type involved is `Sync + Send` and you want to use it with [`Arc`],
47*bd70d2d1SLoGin //! use [`CastFromSync`] in place of [`CastFrom`] and add `[sync]` flag before the list
48*bd70d2d1SLoGin //! of traits in the macros. Refer to the documents for each of macros for details.
49*bd70d2d1SLoGin //!
50*bd70d2d1SLoGin //! For casting, refer to traits defined in [`cast`] module.
51*bd70d2d1SLoGin //!
52*bd70d2d1SLoGin //! [cast_to]: ./attr.cast_to.html
53*bd70d2d1SLoGin //! [castable_to]: ./macro.castable_to.html
54*bd70d2d1SLoGin //! [`CastFrom`]: ./trait.CastFrom.html
55*bd70d2d1SLoGin //! [`CastFromSync`]: ./trait.CastFromSync.html
56*bd70d2d1SLoGin //! [`cast`]: ./cast/index.html
57*bd70d2d1SLoGin //! [`Any`]: https://doc.rust-lang.org/std/any/trait.Any.html
58*bd70d2d1SLoGin //! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
59*bd70d2d1SLoGin 
60*bd70d2d1SLoGin #![cfg_attr(target_os = "none", no_std)]
61*bd70d2d1SLoGin 
62*bd70d2d1SLoGin extern crate alloc;
63*bd70d2d1SLoGin extern crate core;
64*bd70d2d1SLoGin 
65*bd70d2d1SLoGin use core::{
66*bd70d2d1SLoGin     any::{Any, TypeId},
67*bd70d2d1SLoGin     marker::{Send, Sync},
68*bd70d2d1SLoGin };
69*bd70d2d1SLoGin 
70*bd70d2d1SLoGin use alloc::boxed::Box;
71*bd70d2d1SLoGin use alloc::rc::Rc;
72*bd70d2d1SLoGin use alloc::sync::Arc;
73*bd70d2d1SLoGin 
74*bd70d2d1SLoGin use hashbrown::HashMap;
75*bd70d2d1SLoGin use linkme::distributed_slice;
76*bd70d2d1SLoGin 
77*bd70d2d1SLoGin pub use intertrait_macros::*;
78*bd70d2d1SLoGin 
79*bd70d2d1SLoGin use crate::hasher::BuildFastHasher;
80*bd70d2d1SLoGin 
81*bd70d2d1SLoGin pub mod cast;
82*bd70d2d1SLoGin mod hasher;
83*bd70d2d1SLoGin 
84*bd70d2d1SLoGin #[doc(hidden)]
85*bd70d2d1SLoGin pub type BoxedCaster = Box<dyn Any + Send + Sync>;
86*bd70d2d1SLoGin 
87*bd70d2d1SLoGin #[cfg(doctest)]
88*bd70d2d1SLoGin doc_comment::doctest!("../README.md");
89*bd70d2d1SLoGin 
90*bd70d2d1SLoGin /// A distributed slice gathering constructor functions for [`Caster<T>`]s.
91*bd70d2d1SLoGin ///
92*bd70d2d1SLoGin /// A constructor function returns `TypeId` of a concrete type involved in the casting
93*bd70d2d1SLoGin /// and a `Box` of a trait object backed by a [`Caster<T>`].
94*bd70d2d1SLoGin ///
95*bd70d2d1SLoGin /// [`Caster<T>`]: ./struct.Caster.html
96*bd70d2d1SLoGin #[doc(hidden)]
97*bd70d2d1SLoGin #[distributed_slice]
98*bd70d2d1SLoGin pub static CASTERS: [fn() -> (TypeId, BoxedCaster)] = [..];
99*bd70d2d1SLoGin 
100*bd70d2d1SLoGin /// A `HashMap` mapping `TypeId` of a [`Caster<T>`] to an instance of it.
101*bd70d2d1SLoGin ///
102*bd70d2d1SLoGin /// [`Caster<T>`]: ./struct.Caster.html
103*bd70d2d1SLoGin #[cfg(not(target_os = "none"))]
104*bd70d2d1SLoGin static CASTER_MAP: once_cell::sync::Lazy<HashMap<(TypeId, TypeId), BoxedCaster, BuildFastHasher>> =
105*bd70d2d1SLoGin     once_cell::sync::Lazy::new(|| {
106*bd70d2d1SLoGin         CASTERS
107*bd70d2d1SLoGin             .iter()
108*bd70d2d1SLoGin             .map(|f| {
109*bd70d2d1SLoGin                 let (type_id, caster) = f();
110*bd70d2d1SLoGin                 ((type_id, (*caster).type_id()), caster)
111*bd70d2d1SLoGin             })
112*bd70d2d1SLoGin             .collect()
113*bd70d2d1SLoGin     });
114*bd70d2d1SLoGin 
115*bd70d2d1SLoGin /// CasterMap
116*bd70d2d1SLoGin ///
117*bd70d2d1SLoGin /// key.0: type_id of source
118*bd70d2d1SLoGin /// key.1: type_id of target
119*bd70d2d1SLoGin ///
120*bd70d2d1SLoGin /// value: A BoxedCaster which can cast source to target
121*bd70d2d1SLoGin #[cfg(target_os = "none")]
122*bd70d2d1SLoGin static mut CASTER_MAP: Option<HashMap<(TypeId, TypeId), BoxedCaster, BuildFastHasher>> = None;
123*bd70d2d1SLoGin 
124*bd70d2d1SLoGin #[cfg(target_os = "none")]
caster_map() -> &'static HashMap<(TypeId, TypeId), BoxedCaster, BuildFastHasher>125*bd70d2d1SLoGin pub fn caster_map() -> &'static HashMap<(TypeId, TypeId), BoxedCaster, BuildFastHasher> {
126*bd70d2d1SLoGin     return unsafe {
127*bd70d2d1SLoGin         CASTER_MAP.as_ref().unwrap_or_else(|| {
128*bd70d2d1SLoGin             panic!("intertrait_caster_map() must be called after CASTER_MAP is initialized")
129*bd70d2d1SLoGin         })
130*bd70d2d1SLoGin     };
131*bd70d2d1SLoGin }
132*bd70d2d1SLoGin 
133*bd70d2d1SLoGin /// Initializes the global [`CASTER_MAP`] with [`CASTERS`].
134*bd70d2d1SLoGin ///
135*bd70d2d1SLoGin /// no_std环境下,需要手动调用此函数初始化CASTER_MAP
136*bd70d2d1SLoGin #[cfg(target_os = "none")]
init_caster_map()137*bd70d2d1SLoGin pub fn init_caster_map() {
138*bd70d2d1SLoGin     use core::sync::atomic::AtomicBool;
139*bd70d2d1SLoGin 
140*bd70d2d1SLoGin     let pd = AtomicBool::new(false);
141*bd70d2d1SLoGin     let r = pd.compare_exchange(
142*bd70d2d1SLoGin         false,
143*bd70d2d1SLoGin         true,
144*bd70d2d1SLoGin         core::sync::atomic::Ordering::SeqCst,
145*bd70d2d1SLoGin         core::sync::atomic::Ordering::SeqCst,
146*bd70d2d1SLoGin     );
147*bd70d2d1SLoGin 
148*bd70d2d1SLoGin     if r.is_err() {
149*bd70d2d1SLoGin         panic!("init_caster_map() must be called only once");
150*bd70d2d1SLoGin     }
151*bd70d2d1SLoGin 
152*bd70d2d1SLoGin     let hashmap = CASTERS
153*bd70d2d1SLoGin         .iter()
154*bd70d2d1SLoGin         .map(|f| {
155*bd70d2d1SLoGin             let (type_id, caster) = f();
156*bd70d2d1SLoGin             ((type_id, (*caster).type_id()), caster)
157*bd70d2d1SLoGin         })
158*bd70d2d1SLoGin         .collect();
159*bd70d2d1SLoGin 
160*bd70d2d1SLoGin     unsafe { CASTER_MAP = Some(hashmap) };
161*bd70d2d1SLoGin }
162*bd70d2d1SLoGin 
163*bd70d2d1SLoGin #[cfg(not(target_os = "none"))]
init_caster_map()164*bd70d2d1SLoGin pub fn init_caster_map() {}
165*bd70d2d1SLoGin 
cast_arc_panic<T: ?Sized + 'static>(_: Arc<dyn Any + Sync + Send>) -> Arc<T>166*bd70d2d1SLoGin fn cast_arc_panic<T: ?Sized + 'static>(_: Arc<dyn Any + Sync + Send>) -> Arc<T> {
167*bd70d2d1SLoGin     panic!("Prepend [sync] to the list of target traits for Sync + Send types")
168*bd70d2d1SLoGin }
169*bd70d2d1SLoGin 
170*bd70d2d1SLoGin /// A `Caster` knows how to cast a reference to or `Box` of a trait object for `Any`
171*bd70d2d1SLoGin /// to a trait object of trait `T`. Each `Caster` instance is specific to a concrete type.
172*bd70d2d1SLoGin /// That is, it knows how to cast to single specific trait implemented by single specific type.
173*bd70d2d1SLoGin ///
174*bd70d2d1SLoGin /// An implementation of a trait for a concrete type doesn't need to manually provide
175*bd70d2d1SLoGin /// a `Caster`. Instead attach `#[cast_to]` to the `impl` block.
176*bd70d2d1SLoGin #[doc(hidden)]
177*bd70d2d1SLoGin pub struct Caster<T: ?Sized + 'static> {
178*bd70d2d1SLoGin     /// Casts an immutable reference to a trait object for `Any` to a reference
179*bd70d2d1SLoGin     /// to a trait object for trait `T`.
180*bd70d2d1SLoGin     pub cast_ref: fn(from: &dyn Any) -> &T,
181*bd70d2d1SLoGin 
182*bd70d2d1SLoGin     /// Casts a mutable reference to a trait object for `Any` to a mutable reference
183*bd70d2d1SLoGin     /// to a trait object for trait `T`.
184*bd70d2d1SLoGin     pub cast_mut: fn(from: &mut dyn Any) -> &mut T,
185*bd70d2d1SLoGin 
186*bd70d2d1SLoGin     /// Casts a `Box` holding a trait object for `Any` to another `Box` holding a trait object
187*bd70d2d1SLoGin     /// for trait `T`.
188*bd70d2d1SLoGin     pub cast_box: fn(from: Box<dyn Any>) -> Box<T>,
189*bd70d2d1SLoGin 
190*bd70d2d1SLoGin     /// Casts an `Rc` holding a trait object for `Any` to another `Rc` holding a trait object
191*bd70d2d1SLoGin     /// for trait `T`.
192*bd70d2d1SLoGin     pub cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>,
193*bd70d2d1SLoGin 
194*bd70d2d1SLoGin     /// Casts an `Arc` holding a trait object for `Any + Sync + Send + 'static`
195*bd70d2d1SLoGin     /// to another `Arc` holding a trait object for trait `T`.
196*bd70d2d1SLoGin     pub cast_arc: fn(from: Arc<dyn Any + Sync + Send + 'static>) -> Arc<T>,
197*bd70d2d1SLoGin }
198*bd70d2d1SLoGin 
199*bd70d2d1SLoGin impl<T: ?Sized + 'static> Caster<T> {
new( cast_ref: fn(from: &dyn Any) -> &T, cast_mut: fn(from: &mut dyn Any) -> &mut T, cast_box: fn(from: Box<dyn Any>) -> Box<T>, cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>, ) -> Caster<T>200*bd70d2d1SLoGin     pub fn new(
201*bd70d2d1SLoGin         cast_ref: fn(from: &dyn Any) -> &T,
202*bd70d2d1SLoGin         cast_mut: fn(from: &mut dyn Any) -> &mut T,
203*bd70d2d1SLoGin         cast_box: fn(from: Box<dyn Any>) -> Box<T>,
204*bd70d2d1SLoGin         cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>,
205*bd70d2d1SLoGin     ) -> Caster<T> {
206*bd70d2d1SLoGin         Caster::<T> {
207*bd70d2d1SLoGin             cast_ref,
208*bd70d2d1SLoGin             cast_mut,
209*bd70d2d1SLoGin             cast_box,
210*bd70d2d1SLoGin             cast_rc,
211*bd70d2d1SLoGin             cast_arc: cast_arc_panic,
212*bd70d2d1SLoGin         }
213*bd70d2d1SLoGin     }
214*bd70d2d1SLoGin 
new_sync( cast_ref: fn(from: &dyn Any) -> &T, cast_mut: fn(from: &mut dyn Any) -> &mut T, cast_box: fn(from: Box<dyn Any>) -> Box<T>, cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>, cast_arc: fn(from: Arc<dyn Any + Sync + Send>) -> Arc<T>, ) -> Caster<T>215*bd70d2d1SLoGin     pub fn new_sync(
216*bd70d2d1SLoGin         cast_ref: fn(from: &dyn Any) -> &T,
217*bd70d2d1SLoGin         cast_mut: fn(from: &mut dyn Any) -> &mut T,
218*bd70d2d1SLoGin         cast_box: fn(from: Box<dyn Any>) -> Box<T>,
219*bd70d2d1SLoGin         cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>,
220*bd70d2d1SLoGin         cast_arc: fn(from: Arc<dyn Any + Sync + Send>) -> Arc<T>,
221*bd70d2d1SLoGin     ) -> Caster<T> {
222*bd70d2d1SLoGin         Caster::<T> {
223*bd70d2d1SLoGin             cast_ref,
224*bd70d2d1SLoGin             cast_mut,
225*bd70d2d1SLoGin             cast_box,
226*bd70d2d1SLoGin             cast_rc,
227*bd70d2d1SLoGin             cast_arc,
228*bd70d2d1SLoGin         }
229*bd70d2d1SLoGin     }
230*bd70d2d1SLoGin }
231*bd70d2d1SLoGin 
232*bd70d2d1SLoGin /// Returns a `Caster<S, T>` from a concrete type `S` to a trait `T` implemented by it.
233*bd70d2d1SLoGin ///
234*bd70d2d1SLoGin /// ## 参数
235*bd70d2d1SLoGin ///
236*bd70d2d1SLoGin /// - type_id: 源类型的type_id
237*bd70d2d1SLoGin ///
238*bd70d2d1SLoGin /// T: 目标trait
caster<T: ?Sized + 'static>(type_id: TypeId) -> Option<&'static Caster<T>>239*bd70d2d1SLoGin fn caster<T: ?Sized + 'static>(type_id: TypeId) -> Option<&'static Caster<T>> {
240*bd70d2d1SLoGin     #[cfg(not(target_os = "none"))]
241*bd70d2d1SLoGin     {
242*bd70d2d1SLoGin         CASTER_MAP
243*bd70d2d1SLoGin             .get(&(type_id, TypeId::of::<Caster<T>>()))
244*bd70d2d1SLoGin             .and_then(|caster| caster.downcast_ref::<Caster<T>>())
245*bd70d2d1SLoGin     }
246*bd70d2d1SLoGin 
247*bd70d2d1SLoGin     #[cfg(target_os = "none")]
248*bd70d2d1SLoGin     {
249*bd70d2d1SLoGin         caster_map()
250*bd70d2d1SLoGin             .get(&(type_id, TypeId::of::<Caster<T>>()))
251*bd70d2d1SLoGin             .and_then(|caster| caster.downcast_ref::<Caster<T>>())
252*bd70d2d1SLoGin     }
253*bd70d2d1SLoGin }
254*bd70d2d1SLoGin 
255*bd70d2d1SLoGin /// `CastFrom` must be extended by a trait that wants to allow for casting into another trait.
256*bd70d2d1SLoGin ///
257*bd70d2d1SLoGin /// It is used for obtaining a trait object for [`Any`] from a trait object for its sub-trait,
258*bd70d2d1SLoGin /// and blanket implemented for all `Sized + Any + 'static` types.
259*bd70d2d1SLoGin ///
260*bd70d2d1SLoGin /// # Examples
261*bd70d2d1SLoGin /// ```ignore
262*bd70d2d1SLoGin /// trait Source: CastFrom {
263*bd70d2d1SLoGin ///     ...
264*bd70d2d1SLoGin /// }
265*bd70d2d1SLoGin /// ```
266*bd70d2d1SLoGin pub trait CastFrom: Any + 'static {
267*bd70d2d1SLoGin     /// Returns a immutable reference to `Any`, which is backed by the type implementing this trait.
ref_any(&self) -> &dyn Any268*bd70d2d1SLoGin     fn ref_any(&self) -> &dyn Any;
269*bd70d2d1SLoGin 
270*bd70d2d1SLoGin     /// Returns a mutable reference to `Any`, which is backed by the type implementing this trait.
mut_any(&mut self) -> &mut dyn Any271*bd70d2d1SLoGin     fn mut_any(&mut self) -> &mut dyn Any;
272*bd70d2d1SLoGin 
273*bd70d2d1SLoGin     /// Returns a `Box` of `Any`, which is backed by the type implementing this trait.
box_any(self: Box<Self>) -> Box<dyn Any>274*bd70d2d1SLoGin     fn box_any(self: Box<Self>) -> Box<dyn Any>;
275*bd70d2d1SLoGin 
276*bd70d2d1SLoGin     /// Returns an `Rc` of `Any`, which is backed by the type implementing this trait.
rc_any(self: Rc<Self>) -> Rc<dyn Any>277*bd70d2d1SLoGin     fn rc_any(self: Rc<Self>) -> Rc<dyn Any>;
278*bd70d2d1SLoGin }
279*bd70d2d1SLoGin 
280*bd70d2d1SLoGin /// `CastFromSync` must be extended by a trait that is `Any + Sync + Send + 'static`
281*bd70d2d1SLoGin /// and wants to allow for casting into another trait behind references and smart pointers
282*bd70d2d1SLoGin /// especially including `Arc`.
283*bd70d2d1SLoGin ///
284*bd70d2d1SLoGin /// It is used for obtaining a trait object for [`Any + Sync + Send + 'static`] from an object
285*bd70d2d1SLoGin /// for its sub-trait, and blanket implemented for all `Sized + Sync + Send + 'static` types.
286*bd70d2d1SLoGin ///
287*bd70d2d1SLoGin /// # Examples
288*bd70d2d1SLoGin /// ```ignore
289*bd70d2d1SLoGin /// trait Source: CastFromSync {
290*bd70d2d1SLoGin ///     ...
291*bd70d2d1SLoGin /// }
292*bd70d2d1SLoGin /// ```
293*bd70d2d1SLoGin pub trait CastFromSync: CastFrom + Sync + Send + 'static {
arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static>294*bd70d2d1SLoGin     fn arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static>;
295*bd70d2d1SLoGin }
296*bd70d2d1SLoGin 
297*bd70d2d1SLoGin impl<T: Sized + Any + 'static> CastFrom for T {
ref_any(&self) -> &dyn Any298*bd70d2d1SLoGin     fn ref_any(&self) -> &dyn Any {
299*bd70d2d1SLoGin         self
300*bd70d2d1SLoGin     }
301*bd70d2d1SLoGin 
mut_any(&mut self) -> &mut dyn Any302*bd70d2d1SLoGin     fn mut_any(&mut self) -> &mut dyn Any {
303*bd70d2d1SLoGin         self
304*bd70d2d1SLoGin     }
305*bd70d2d1SLoGin 
box_any(self: Box<Self>) -> Box<dyn Any>306*bd70d2d1SLoGin     fn box_any(self: Box<Self>) -> Box<dyn Any> {
307*bd70d2d1SLoGin         self
308*bd70d2d1SLoGin     }
309*bd70d2d1SLoGin 
rc_any(self: Rc<Self>) -> Rc<dyn Any>310*bd70d2d1SLoGin     fn rc_any(self: Rc<Self>) -> Rc<dyn Any> {
311*bd70d2d1SLoGin         self
312*bd70d2d1SLoGin     }
313*bd70d2d1SLoGin }
314*bd70d2d1SLoGin 
315*bd70d2d1SLoGin impl CastFrom for dyn Any + 'static {
ref_any(&self) -> &dyn Any316*bd70d2d1SLoGin     fn ref_any(&self) -> &dyn Any {
317*bd70d2d1SLoGin         self
318*bd70d2d1SLoGin     }
319*bd70d2d1SLoGin 
mut_any(&mut self) -> &mut dyn Any320*bd70d2d1SLoGin     fn mut_any(&mut self) -> &mut dyn Any {
321*bd70d2d1SLoGin         self
322*bd70d2d1SLoGin     }
323*bd70d2d1SLoGin 
box_any(self: Box<Self>) -> Box<dyn Any>324*bd70d2d1SLoGin     fn box_any(self: Box<Self>) -> Box<dyn Any> {
325*bd70d2d1SLoGin         self
326*bd70d2d1SLoGin     }
327*bd70d2d1SLoGin 
rc_any(self: Rc<Self>) -> Rc<dyn Any>328*bd70d2d1SLoGin     fn rc_any(self: Rc<Self>) -> Rc<dyn Any> {
329*bd70d2d1SLoGin         self
330*bd70d2d1SLoGin     }
331*bd70d2d1SLoGin }
332*bd70d2d1SLoGin 
333*bd70d2d1SLoGin impl<T: Sized + Sync + Send + 'static> CastFromSync for T {
arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static>334*bd70d2d1SLoGin     fn arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static> {
335*bd70d2d1SLoGin         self
336*bd70d2d1SLoGin     }
337*bd70d2d1SLoGin }
338*bd70d2d1SLoGin 
339*bd70d2d1SLoGin impl CastFrom for dyn Any + Sync + Send + 'static {
ref_any(&self) -> &dyn Any340*bd70d2d1SLoGin     fn ref_any(&self) -> &dyn Any {
341*bd70d2d1SLoGin         self
342*bd70d2d1SLoGin     }
343*bd70d2d1SLoGin 
mut_any(&mut self) -> &mut dyn Any344*bd70d2d1SLoGin     fn mut_any(&mut self) -> &mut dyn Any {
345*bd70d2d1SLoGin         self
346*bd70d2d1SLoGin     }
347*bd70d2d1SLoGin 
box_any(self: Box<Self>) -> Box<dyn Any>348*bd70d2d1SLoGin     fn box_any(self: Box<Self>) -> Box<dyn Any> {
349*bd70d2d1SLoGin         self
350*bd70d2d1SLoGin     }
351*bd70d2d1SLoGin 
rc_any(self: Rc<Self>) -> Rc<dyn Any>352*bd70d2d1SLoGin     fn rc_any(self: Rc<Self>) -> Rc<dyn Any> {
353*bd70d2d1SLoGin         self
354*bd70d2d1SLoGin     }
355*bd70d2d1SLoGin }
356*bd70d2d1SLoGin 
357*bd70d2d1SLoGin impl CastFromSync for dyn Any + Sync + Send + 'static {
arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static>358*bd70d2d1SLoGin     fn arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static> {
359*bd70d2d1SLoGin         self
360*bd70d2d1SLoGin     }
361*bd70d2d1SLoGin }
362*bd70d2d1SLoGin 
363*bd70d2d1SLoGin #[cfg(test)]
364*bd70d2d1SLoGin mod tests {
365*bd70d2d1SLoGin     extern crate std;
366*bd70d2d1SLoGin     use std::any::{Any, TypeId};
367*bd70d2d1SLoGin     use std::fmt::{Debug, Display};
368*bd70d2d1SLoGin 
369*bd70d2d1SLoGin     use linkme::distributed_slice;
370*bd70d2d1SLoGin 
371*bd70d2d1SLoGin     use crate::{BoxedCaster, CastFromSync};
372*bd70d2d1SLoGin 
373*bd70d2d1SLoGin     use super::cast::*;
374*bd70d2d1SLoGin     use super::*;
375*bd70d2d1SLoGin 
376*bd70d2d1SLoGin     #[distributed_slice(super::CASTERS)]
377*bd70d2d1SLoGin     static TEST_CASTER: fn() -> (TypeId, BoxedCaster) = create_test_caster;
378*bd70d2d1SLoGin 
379*bd70d2d1SLoGin     #[derive(Debug)]
380*bd70d2d1SLoGin     struct TestStruct;
381*bd70d2d1SLoGin 
382*bd70d2d1SLoGin     trait SourceTrait: CastFromSync {}
383*bd70d2d1SLoGin 
384*bd70d2d1SLoGin     impl SourceTrait for TestStruct {}
385*bd70d2d1SLoGin 
create_test_caster() -> (TypeId, BoxedCaster)386*bd70d2d1SLoGin     fn create_test_caster() -> (TypeId, BoxedCaster) {
387*bd70d2d1SLoGin         let type_id = TypeId::of::<TestStruct>();
388*bd70d2d1SLoGin         let caster = Box::new(Caster::<dyn Debug> {
389*bd70d2d1SLoGin             cast_ref: |from| from.downcast_ref::<TestStruct>().unwrap(),
390*bd70d2d1SLoGin             cast_mut: |from| from.downcast_mut::<TestStruct>().unwrap(),
391*bd70d2d1SLoGin             cast_box: |from| from.downcast::<TestStruct>().unwrap(),
392*bd70d2d1SLoGin             cast_rc: |from| from.downcast::<TestStruct>().unwrap(),
393*bd70d2d1SLoGin             cast_arc: |from| from.downcast::<TestStruct>().unwrap(),
394*bd70d2d1SLoGin         });
395*bd70d2d1SLoGin         (type_id, caster)
396*bd70d2d1SLoGin     }
397*bd70d2d1SLoGin 
398*bd70d2d1SLoGin     #[test]
cast_ref()399*bd70d2d1SLoGin     fn cast_ref() {
400*bd70d2d1SLoGin         let ts = TestStruct;
401*bd70d2d1SLoGin         let st: &dyn SourceTrait = &ts;
402*bd70d2d1SLoGin         let debug = st.cast::<dyn Debug>();
403*bd70d2d1SLoGin         assert!(debug.is_some());
404*bd70d2d1SLoGin     }
405*bd70d2d1SLoGin 
406*bd70d2d1SLoGin     #[test]
cast_mut()407*bd70d2d1SLoGin     fn cast_mut() {
408*bd70d2d1SLoGin         let mut ts = TestStruct;
409*bd70d2d1SLoGin         let st: &mut dyn SourceTrait = &mut ts;
410*bd70d2d1SLoGin         let debug = st.cast::<dyn Debug>();
411*bd70d2d1SLoGin         assert!(debug.is_some());
412*bd70d2d1SLoGin     }
413*bd70d2d1SLoGin 
414*bd70d2d1SLoGin     #[test]
cast_box()415*bd70d2d1SLoGin     fn cast_box() {
416*bd70d2d1SLoGin         let ts = Box::new(TestStruct);
417*bd70d2d1SLoGin         let st: Box<dyn SourceTrait> = ts;
418*bd70d2d1SLoGin         let debug = st.cast::<dyn Debug>();
419*bd70d2d1SLoGin         assert!(debug.is_ok());
420*bd70d2d1SLoGin     }
421*bd70d2d1SLoGin 
422*bd70d2d1SLoGin     #[test]
cast_rc()423*bd70d2d1SLoGin     fn cast_rc() {
424*bd70d2d1SLoGin         let ts = Rc::new(TestStruct);
425*bd70d2d1SLoGin         let st: Rc<dyn SourceTrait> = ts;
426*bd70d2d1SLoGin         let debug = st.cast::<dyn Debug>();
427*bd70d2d1SLoGin         assert!(debug.is_ok());
428*bd70d2d1SLoGin     }
429*bd70d2d1SLoGin 
430*bd70d2d1SLoGin     #[test]
cast_arc()431*bd70d2d1SLoGin     fn cast_arc() {
432*bd70d2d1SLoGin         let ts = Arc::new(TestStruct);
433*bd70d2d1SLoGin         let st: Arc<dyn SourceTrait> = ts;
434*bd70d2d1SLoGin         let debug = st.cast::<dyn Debug>();
435*bd70d2d1SLoGin         assert!(debug.is_ok());
436*bd70d2d1SLoGin     }
437*bd70d2d1SLoGin 
438*bd70d2d1SLoGin     #[test]
cast_ref_wrong()439*bd70d2d1SLoGin     fn cast_ref_wrong() {
440*bd70d2d1SLoGin         let ts = TestStruct;
441*bd70d2d1SLoGin         let st: &dyn SourceTrait = &ts;
442*bd70d2d1SLoGin         let display = st.cast::<dyn Display>();
443*bd70d2d1SLoGin         assert!(display.is_none());
444*bd70d2d1SLoGin     }
445*bd70d2d1SLoGin 
446*bd70d2d1SLoGin     #[test]
cast_mut_wrong()447*bd70d2d1SLoGin     fn cast_mut_wrong() {
448*bd70d2d1SLoGin         let mut ts = TestStruct;
449*bd70d2d1SLoGin         let st: &mut dyn SourceTrait = &mut ts;
450*bd70d2d1SLoGin         let display = st.cast::<dyn Display>();
451*bd70d2d1SLoGin         assert!(display.is_none());
452*bd70d2d1SLoGin     }
453*bd70d2d1SLoGin 
454*bd70d2d1SLoGin     #[test]
cast_box_wrong()455*bd70d2d1SLoGin     fn cast_box_wrong() {
456*bd70d2d1SLoGin         let ts = Box::new(TestStruct);
457*bd70d2d1SLoGin         let st: Box<dyn SourceTrait> = ts;
458*bd70d2d1SLoGin         let display = st.cast::<dyn Display>();
459*bd70d2d1SLoGin         assert!(display.is_err());
460*bd70d2d1SLoGin     }
461*bd70d2d1SLoGin 
462*bd70d2d1SLoGin     #[test]
cast_rc_wrong()463*bd70d2d1SLoGin     fn cast_rc_wrong() {
464*bd70d2d1SLoGin         let ts = Rc::new(TestStruct);
465*bd70d2d1SLoGin         let st: Rc<dyn SourceTrait> = ts;
466*bd70d2d1SLoGin         let display = st.cast::<dyn Display>();
467*bd70d2d1SLoGin         assert!(display.is_err());
468*bd70d2d1SLoGin     }
469*bd70d2d1SLoGin 
470*bd70d2d1SLoGin     #[test]
cast_arc_wrong()471*bd70d2d1SLoGin     fn cast_arc_wrong() {
472*bd70d2d1SLoGin         let ts = Arc::new(TestStruct);
473*bd70d2d1SLoGin         let st: Arc<dyn SourceTrait> = ts;
474*bd70d2d1SLoGin         let display = st.cast::<dyn Display>();
475*bd70d2d1SLoGin         assert!(display.is_err());
476*bd70d2d1SLoGin     }
477*bd70d2d1SLoGin 
478*bd70d2d1SLoGin     #[test]
cast_ref_from_any()479*bd70d2d1SLoGin     fn cast_ref_from_any() {
480*bd70d2d1SLoGin         let ts = TestStruct;
481*bd70d2d1SLoGin         let st: &dyn Any = &ts;
482*bd70d2d1SLoGin         let debug = st.cast::<dyn Debug>();
483*bd70d2d1SLoGin         assert!(debug.is_some());
484*bd70d2d1SLoGin     }
485*bd70d2d1SLoGin 
486*bd70d2d1SLoGin     #[test]
cast_mut_from_any()487*bd70d2d1SLoGin     fn cast_mut_from_any() {
488*bd70d2d1SLoGin         let mut ts = TestStruct;
489*bd70d2d1SLoGin         let st: &mut dyn Any = &mut ts;
490*bd70d2d1SLoGin         let debug = st.cast::<dyn Debug>();
491*bd70d2d1SLoGin         assert!(debug.is_some());
492*bd70d2d1SLoGin     }
493*bd70d2d1SLoGin 
494*bd70d2d1SLoGin     #[test]
cast_box_from_any()495*bd70d2d1SLoGin     fn cast_box_from_any() {
496*bd70d2d1SLoGin         let ts = Box::new(TestStruct);
497*bd70d2d1SLoGin         let st: Box<dyn Any> = ts;
498*bd70d2d1SLoGin         let debug = st.cast::<dyn Debug>();
499*bd70d2d1SLoGin         assert!(debug.is_ok());
500*bd70d2d1SLoGin     }
501*bd70d2d1SLoGin 
502*bd70d2d1SLoGin     #[test]
cast_rc_from_any()503*bd70d2d1SLoGin     fn cast_rc_from_any() {
504*bd70d2d1SLoGin         let ts = Rc::new(TestStruct);
505*bd70d2d1SLoGin         let st: Rc<dyn Any> = ts;
506*bd70d2d1SLoGin         let debug = st.cast::<dyn Debug>();
507*bd70d2d1SLoGin         assert!(debug.is_ok());
508*bd70d2d1SLoGin     }
509*bd70d2d1SLoGin 
510*bd70d2d1SLoGin     #[test]
cast_arc_from_any()511*bd70d2d1SLoGin     fn cast_arc_from_any() {
512*bd70d2d1SLoGin         let ts = Arc::new(TestStruct);
513*bd70d2d1SLoGin         let st: Arc<dyn Any + Send + Sync> = ts;
514*bd70d2d1SLoGin         let debug = st.cast::<dyn Debug>();
515*bd70d2d1SLoGin         assert!(debug.is_ok());
516*bd70d2d1SLoGin     }
517*bd70d2d1SLoGin 
518*bd70d2d1SLoGin     #[test]
impls_ref()519*bd70d2d1SLoGin     fn impls_ref() {
520*bd70d2d1SLoGin         let ts = TestStruct;
521*bd70d2d1SLoGin         let st: &dyn SourceTrait = &ts;
522*bd70d2d1SLoGin         assert!(st.impls::<dyn Debug>());
523*bd70d2d1SLoGin     }
524*bd70d2d1SLoGin 
525*bd70d2d1SLoGin     #[test]
impls_mut()526*bd70d2d1SLoGin     fn impls_mut() {
527*bd70d2d1SLoGin         let mut ts = TestStruct;
528*bd70d2d1SLoGin         let st: &mut dyn SourceTrait = &mut ts;
529*bd70d2d1SLoGin         assert!((*st).impls::<dyn Debug>());
530*bd70d2d1SLoGin     }
531*bd70d2d1SLoGin 
532*bd70d2d1SLoGin     #[test]
impls_box()533*bd70d2d1SLoGin     fn impls_box() {
534*bd70d2d1SLoGin         let ts = Box::new(TestStruct);
535*bd70d2d1SLoGin         let st: Box<dyn SourceTrait> = ts;
536*bd70d2d1SLoGin         assert!((*st).impls::<dyn Debug>());
537*bd70d2d1SLoGin     }
538*bd70d2d1SLoGin 
539*bd70d2d1SLoGin     #[test]
impls_rc()540*bd70d2d1SLoGin     fn impls_rc() {
541*bd70d2d1SLoGin         let ts = Rc::new(TestStruct);
542*bd70d2d1SLoGin         let st: Rc<dyn SourceTrait> = ts;
543*bd70d2d1SLoGin         assert!((*st).impls::<dyn Debug>());
544*bd70d2d1SLoGin     }
545*bd70d2d1SLoGin 
546*bd70d2d1SLoGin     #[test]
impls_arc()547*bd70d2d1SLoGin     fn impls_arc() {
548*bd70d2d1SLoGin         let ts = Arc::new(TestStruct);
549*bd70d2d1SLoGin         let st: Arc<dyn SourceTrait> = ts;
550*bd70d2d1SLoGin         assert!((*st).impls::<dyn Debug>());
551*bd70d2d1SLoGin     }
552*bd70d2d1SLoGin 
553*bd70d2d1SLoGin     #[test]
impls_not_ref()554*bd70d2d1SLoGin     fn impls_not_ref() {
555*bd70d2d1SLoGin         let ts = TestStruct;
556*bd70d2d1SLoGin         let st: &dyn SourceTrait = &ts;
557*bd70d2d1SLoGin         assert!(!st.impls::<dyn Display>());
558*bd70d2d1SLoGin     }
559*bd70d2d1SLoGin 
560*bd70d2d1SLoGin     #[test]
impls_not_mut()561*bd70d2d1SLoGin     fn impls_not_mut() {
562*bd70d2d1SLoGin         let mut ts = TestStruct;
563*bd70d2d1SLoGin         let st: &mut dyn Any = &mut ts;
564*bd70d2d1SLoGin         assert!(!(*st).impls::<dyn Display>());
565*bd70d2d1SLoGin     }
566*bd70d2d1SLoGin 
567*bd70d2d1SLoGin     #[test]
impls_not_box()568*bd70d2d1SLoGin     fn impls_not_box() {
569*bd70d2d1SLoGin         let ts = Box::new(TestStruct);
570*bd70d2d1SLoGin         let st: Box<dyn SourceTrait> = ts;
571*bd70d2d1SLoGin         assert!(!st.impls::<dyn Display>());
572*bd70d2d1SLoGin     }
573*bd70d2d1SLoGin 
574*bd70d2d1SLoGin     #[test]
impls_not_rc()575*bd70d2d1SLoGin     fn impls_not_rc() {
576*bd70d2d1SLoGin         let ts = Rc::new(TestStruct);
577*bd70d2d1SLoGin         let st: Rc<dyn SourceTrait> = ts;
578*bd70d2d1SLoGin         assert!(!(*st).impls::<dyn Display>());
579*bd70d2d1SLoGin     }
580*bd70d2d1SLoGin 
581*bd70d2d1SLoGin     #[test]
impls_not_arc()582*bd70d2d1SLoGin     fn impls_not_arc() {
583*bd70d2d1SLoGin         let ts = Arc::new(TestStruct);
584*bd70d2d1SLoGin         let st: Arc<dyn SourceTrait> = ts;
585*bd70d2d1SLoGin         assert!(!(*st).impls::<dyn Display>());
586*bd70d2d1SLoGin     }
587*bd70d2d1SLoGin }
588