Skip to main content

intertrait/cast/
cast_mut.rs

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