1 use alloc::boxed::Box; 2 3 use crate::{caster, CastFrom}; 4 5 /// A trait that is blanket-implemented for traits extending `CastFrom` to allow for casting 6 /// of a trait object for it behind a `Box` to a trait object for another trait 7 /// implemented by the underlying value. 8 /// 9 /// # Examples 10 /// ``` 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 = Box::new(Data); 27 /// let source: Box<dyn Source> = data; 28 /// let greet = source.cast::<dyn Greet>(); 29 /// greet.unwrap_or_else(|_| panic!("casting failed")).greet(); 30 /// ``` 31 pub trait CastBox { 32 /// Casts a box to this trait into that of type `T`. If fails, returns the receiver. 33 fn cast<T: ?Sized + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>>; 34 } 35 36 /// A blanket implementation of `CastBox` for traits extending `CastFrom`. 37 impl<S: ?Sized + CastFrom> CastBox for S { 38 fn cast<T: ?Sized + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> { 39 match caster::<T>((*self).type_id()) { 40 Some(caster) => Ok((caster.cast_box)(self.box_any())), 41 None => Err(self), 42 } 43 } 44 } 45