cast_mut.rs 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. use crate::{caster, CastFrom};
  2. /// A trait that is blanket-implemented for traits extending `CastFrom` to allow for casting
  3. /// of a trait object for it behind an mutable reference to a trait object for another trait
  4. /// implemented by the underlying value.
  5. ///
  6. /// # Examples
  7. /// ```
  8. /// # use intertrait::*;
  9. /// use intertrait::cast::*;
  10. ///
  11. /// # #[cast_to(Greet)]
  12. /// # struct Data;
  13. /// # trait Source: CastFrom {}
  14. /// # trait Greet {
  15. /// # fn greet(&self);
  16. /// # }
  17. /// # impl Greet for Data {
  18. /// # fn greet(&self) {
  19. /// # println!("Hello");
  20. /// # }
  21. /// # }
  22. /// impl Source for Data {}
  23. /// let mut data = Data;
  24. /// let source: &mut dyn Source = &mut data;
  25. /// let greet = source.cast::<dyn Greet>();
  26. /// greet.unwrap().greet();
  27. /// ```
  28. pub trait CastMut {
  29. /// Casts a mutable reference to this trait into that of type `T`.
  30. fn cast<T: ?Sized + 'static>(&mut self) -> Option<&mut T>;
  31. }
  32. /// A blanket implementation of `CastMut` for traits extending `CastFrom`.
  33. impl<S: ?Sized + CastFrom> CastMut for S {
  34. fn cast<T: ?Sized + 'static>(&mut self) -> Option<&mut T> {
  35. let any = self.mut_any();
  36. let caster = caster::<T>((*any).type_id())?;
  37. (caster.cast_mut)(any).into()
  38. }
  39. }