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