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