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