xref: /DragonOS/kernel/crates/intertrait/src/cast/cast_mut.rs (revision c635d8a9cfe25bc11779f323ef0c7d7a0f597d4a)
1 use 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 /// ```
29 pub 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`.
35 impl<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 }
42