1*bd70d2d1SLoGin use core::any::TypeId; 2*bd70d2d1SLoGin 3*bd70d2d1SLoGin use crate::{caster, CastFrom, Caster}; 4*bd70d2d1SLoGin 5*bd70d2d1SLoGin /// A trait that is blanket-implemented for traits extending `CastFrom` to allow for casting 6*bd70d2d1SLoGin /// of a trait object for it behind an immutable reference to a trait object for another trait 7*bd70d2d1SLoGin /// implemented by the underlying value. 8*bd70d2d1SLoGin /// 9*bd70d2d1SLoGin /// # Examples 10*bd70d2d1SLoGin /// ## Casting an immutable reference 11*bd70d2d1SLoGin /// ``` 12*bd70d2d1SLoGin /// # use intertrait::*; 13*bd70d2d1SLoGin /// use intertrait::cast::*; 14*bd70d2d1SLoGin /// 15*bd70d2d1SLoGin /// # #[cast_to(Greet)] 16*bd70d2d1SLoGin /// # struct Data; 17*bd70d2d1SLoGin /// # trait Source: CastFrom {} 18*bd70d2d1SLoGin /// # trait Greet { 19*bd70d2d1SLoGin /// # fn greet(&self); 20*bd70d2d1SLoGin /// # } 21*bd70d2d1SLoGin /// # impl Greet for Data { 22*bd70d2d1SLoGin /// # fn greet(&self) { 23*bd70d2d1SLoGin /// # println!("Hello"); 24*bd70d2d1SLoGin /// # } 25*bd70d2d1SLoGin /// # } 26*bd70d2d1SLoGin /// impl Source for Data {} 27*bd70d2d1SLoGin /// let data = Data; 28*bd70d2d1SLoGin /// let source: &dyn Source = &data; 29*bd70d2d1SLoGin /// let greet = source.cast::<dyn Greet>(); 30*bd70d2d1SLoGin /// greet.unwrap().greet(); 31*bd70d2d1SLoGin /// ``` 32*bd70d2d1SLoGin /// 33*bd70d2d1SLoGin /// ## Testing if a cast is possible 34*bd70d2d1SLoGin /// ``` 35*bd70d2d1SLoGin /// # use intertrait::*; 36*bd70d2d1SLoGin /// use intertrait::cast::*; 37*bd70d2d1SLoGin /// 38*bd70d2d1SLoGin /// # #[cast_to(Greet)] 39*bd70d2d1SLoGin /// # struct Data; 40*bd70d2d1SLoGin /// # trait Source: CastFrom {} 41*bd70d2d1SLoGin /// # trait Greet { 42*bd70d2d1SLoGin /// # fn greet(&self); 43*bd70d2d1SLoGin /// # } 44*bd70d2d1SLoGin /// # impl Greet for Data { 45*bd70d2d1SLoGin /// # fn greet(&self) { 46*bd70d2d1SLoGin /// # println!("Hello"); 47*bd70d2d1SLoGin /// # } 48*bd70d2d1SLoGin /// # } 49*bd70d2d1SLoGin /// impl Source for Data {} 50*bd70d2d1SLoGin /// let data = Data; 51*bd70d2d1SLoGin /// let source: &dyn Source = &data; 52*bd70d2d1SLoGin /// assert!(source.impls::<dyn Greet>()); 53*bd70d2d1SLoGin /// assert!(!source.impls::<dyn std::fmt::Debug>()); 54*bd70d2d1SLoGin /// ``` 55*bd70d2d1SLoGin pub trait CastRef { 56*bd70d2d1SLoGin /// Casts a reference to this trait into that of type `T`. cast<T: ?Sized + 'static>(&self) -> Option<&T>57*bd70d2d1SLoGin fn cast<T: ?Sized + 'static>(&self) -> Option<&T>; 58*bd70d2d1SLoGin 59*bd70d2d1SLoGin /// Tests if this trait object can be cast into `T`. impls<T: ?Sized + 'static>(&self) -> bool60*bd70d2d1SLoGin fn impls<T: ?Sized + 'static>(&self) -> bool; 61*bd70d2d1SLoGin } 62*bd70d2d1SLoGin 63*bd70d2d1SLoGin /// A blanket implementation of `CastRef` for traits extending `CastFrom`. 64*bd70d2d1SLoGin impl<S: ?Sized + CastFrom> CastRef for S { cast<T: ?Sized + 'static>(&self) -> Option<&T>65*bd70d2d1SLoGin fn cast<T: ?Sized + 'static>(&self) -> Option<&T> { 66*bd70d2d1SLoGin let any = self.ref_any(); 67*bd70d2d1SLoGin // 获取从 self 到 T 的转换器,如果不存在则返回 None 68*bd70d2d1SLoGin let caster = caster::<T>(any.type_id())?; 69*bd70d2d1SLoGin (caster.cast_ref)(any).into() 70*bd70d2d1SLoGin } 71*bd70d2d1SLoGin 72*bd70d2d1SLoGin #[cfg(not(target_os = "none"))] impls<T: ?Sized + 'static>(&self) -> bool73*bd70d2d1SLoGin fn impls<T: ?Sized + 'static>(&self) -> bool { 74*bd70d2d1SLoGin use crate::CASTER_MAP; 75*bd70d2d1SLoGin CASTER_MAP.contains_key(&(self.type_id(), TypeId::of::<Caster<T>>())) 76*bd70d2d1SLoGin } 77*bd70d2d1SLoGin 78*bd70d2d1SLoGin #[cfg(target_os = "none")] impls<T: ?Sized + 'static>(&self) -> bool79*bd70d2d1SLoGin fn impls<T: ?Sized + 'static>(&self) -> bool { 80*bd70d2d1SLoGin use crate::caster_map; 81*bd70d2d1SLoGin 82*bd70d2d1SLoGin caster_map().contains_key(&(self.type_id(), TypeId::of::<Caster<T>>())) 83*bd70d2d1SLoGin } 84*bd70d2d1SLoGin } 85