cast_rc.rs 1.3 KB

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