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