xref: /DragonOS/kernel/src/libs/casting.rs (revision 8d72b68da9339ec97e1b8929bcf2946f0fd83cd5)
1 // Copyright (C) DragonOS Community  longjin 2023
2 
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
7 
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 // Or you can visit https://www.gnu.org/licenses/gpl-2.0.html
17 #![allow(dead_code)]
18 
19 use core::any::Any;
20 
21 use alloc::sync::Arc;
22 
23 /// @brief 将Arc<dyn xxx>转换为Arc<具体类型>的trait
24 ///
25 /// 用法:
26 ///
27 /// ```rust
28 /// trait Base: Any + Send + Sync + Debug {
29 ///     fn get_name(&self) -> String;
30 /// }
31 ///
32 /// struct A {
33 ///    name: String,
34 /// }
35 ///
36 /// impl DowncastArc for dyn Base {
37 ///     fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> {
38 ///         return self;
39 ///     }
40 /// }
41 ///
42 /// impl Base for A {
43 ///    fn get_name(&self) -> String {
44 ///       return self.name.clone();
45 ///   }
46 /// }
47 ///
48 /// fn test() {
49 ///     let a = A { name: "a".to_string() };
50 
51 ///     let a_arc: Arc<dyn Base> = Arc::new(a) as Arc<dyn Base>;
52 ///     let a_arc2: Option<Arc<A>> = a_arc.downcast_arc::<A>();
53 ///     assert!(a_arc2.is_some());
54 /// }
55 /// ```
56 pub trait DowncastArc: Any + Send + Sync {
57     /// 请在具体类型中实现这个函数,返回self
58     fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any>;
59 
60     /// @brief 将Arc<dyn xxx>转换为Arc<具体类型>
61     ///
62     /// 如果Arc<dyn xxx>是Arc<具体类型>,则返回Some(Arc<具体类型>),否则返回None
63     ///
64     /// @param self Arc<dyn xxx>
65     fn downcast_arc<T: Any + Send + Sync>(self: Arc<Self>) -> Option<Arc<T>> {
66         let x: Arc<dyn Any> = self.as_any_arc();
67         if x.is::<T>() {
68             // into_raw不会改变引用计数
69             let p = Arc::into_raw(x);
70             let new = unsafe { Arc::from_raw(p as *const T) };
71             return Some(new);
72         }
73         return None;
74     }
75 }
76