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