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}