1*bd70d2d1SLoGin use alloc::sync::Arc; 2*bd70d2d1SLoGin 3*bd70d2d1SLoGin use crate::{caster, CastFromSync}; 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 `Rc` to a trait object for another trait 7*bd70d2d1SLoGin /// implemented by the underlying value. 8*bd70d2d1SLoGin /// 9*bd70d2d1SLoGin /// # Examples 10*bd70d2d1SLoGin /// ``` 11*bd70d2d1SLoGin /// # use std::sync::Arc; 12*bd70d2d1SLoGin /// # use intertrait::*; 13*bd70d2d1SLoGin /// use intertrait::cast::*; 14*bd70d2d1SLoGin /// 15*bd70d2d1SLoGin /// # #[cast_to([sync] 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 = Arc::new(data); 29*bd70d2d1SLoGin /// let greet = source.cast::<dyn Greet>(); 30*bd70d2d1SLoGin /// greet.unwrap_or_else(|_| panic!("must not happen")).greet(); 31*bd70d2d1SLoGin /// ``` 32*bd70d2d1SLoGin pub trait CastArc { 33*bd70d2d1SLoGin /// Casts an `Arc` for this trait into that for type `T`. cast<T: ?Sized + 'static>(self: Arc<Self>) -> Result<Arc<T>, Arc<Self>>34*bd70d2d1SLoGin fn cast<T: ?Sized + 'static>(self: Arc<Self>) -> Result<Arc<T>, Arc<Self>>; 35*bd70d2d1SLoGin } 36*bd70d2d1SLoGin 37*bd70d2d1SLoGin /// A blanket implementation of `CastArc` for traits extending `CastFrom`, `Sync`, and `Send`. 38*bd70d2d1SLoGin impl<S: ?Sized + CastFromSync> CastArc for S { cast<T: ?Sized + 'static>(self: Arc<Self>) -> Result<Arc<T>, Arc<Self>>39*bd70d2d1SLoGin fn cast<T: ?Sized + 'static>(self: Arc<Self>) -> Result<Arc<T>, Arc<Self>> { 40*bd70d2d1SLoGin match caster::<T>((*self).type_id()) { 41*bd70d2d1SLoGin Some(caster) => Ok((caster.cast_arc)(self.arc_any())), 42*bd70d2d1SLoGin None => Err(self), 43*bd70d2d1SLoGin } 44*bd70d2d1SLoGin } 45*bd70d2d1SLoGin } 46