177c928f6Slogin // Copyright (C) DragonOS Community longjin 2023 277c928f6Slogin 377c928f6Slogin // This program is free software; you can redistribute it and/or 477c928f6Slogin // modify it under the terms of the GNU General Public License 577c928f6Slogin // as published by the Free Software Foundation; either version 2 677c928f6Slogin // of the License, or (at your option) any later version. 777c928f6Slogin 877c928f6Slogin // This program is distributed in the hope that it will be useful, 977c928f6Slogin // but WITHOUT ANY WARRANTY; without even the implied warranty of 1077c928f6Slogin // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1177c928f6Slogin // GNU General Public License for more details. 1277c928f6Slogin 1377c928f6Slogin // You should have received a copy of the GNU General Public License 1477c928f6Slogin // along with this program; if not, write to the Free Software 1577c928f6Slogin // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 1677c928f6Slogin // Or you can visit https://www.gnu.org/licenses/gpl-2.0.html 1777c928f6Slogin #![allow(dead_code)] 1877c928f6Slogin 1977c928f6Slogin use core::any::Any; 2077c928f6Slogin 2177c928f6Slogin use alloc::sync::Arc; 2277c928f6Slogin 2377c928f6Slogin /// @brief 将Arc<dyn xxx>转换为Arc<具体类型>的trait 2477c928f6Slogin /// 2577c928f6Slogin /// 用法: 2677c928f6Slogin /// 2777c928f6Slogin /// ```rust 2877c928f6Slogin /// trait Base: Any + Send + Sync + Debug { 2977c928f6Slogin /// fn get_name(&self) -> String; 3077c928f6Slogin /// } 3177c928f6Slogin /// 3277c928f6Slogin /// struct A { 3377c928f6Slogin /// name: String, 3477c928f6Slogin /// } 3577c928f6Slogin /// 3677c928f6Slogin /// impl DowncastArc for dyn Base { 3777c928f6Slogin /// fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> { 3877c928f6Slogin /// return self; 3977c928f6Slogin /// } 4077c928f6Slogin /// } 4177c928f6Slogin /// 4277c928f6Slogin /// impl Base for A { 4377c928f6Slogin /// fn get_name(&self) -> String { 4477c928f6Slogin /// return self.name.clone(); 4577c928f6Slogin /// } 4677c928f6Slogin /// } 4777c928f6Slogin /// 4877c928f6Slogin /// fn test() { 4977c928f6Slogin /// let a = A { name: "a".to_string() }; 5077c928f6Slogin 5177c928f6Slogin /// let a_arc: Arc<dyn Base> = Arc::new(a) as Arc<dyn Base>; 5277c928f6Slogin /// let a_arc2: Option<Arc<A>> = a_arc.downcast_arc::<A>(); 5377c928f6Slogin /// assert!(a_arc2.is_some()); 5477c928f6Slogin /// } 5577c928f6Slogin /// ``` 56*cde5492fSlogin pub trait DowncastArc: Any + Send + Sync { 5777c928f6Slogin /// 请在具体类型中实现这个函数,返回self as_any_arc(self: Arc<Self>) -> Arc<dyn Any>5877c928f6Slogin fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any>; 5977c928f6Slogin 6077c928f6Slogin /// @brief 将Arc<dyn xxx>转换为Arc<具体类型> 6177c928f6Slogin /// 6277c928f6Slogin /// 如果Arc<dyn xxx>是Arc<具体类型>,则返回Some(Arc<具体类型>),否则返回None 6377c928f6Slogin /// 6477c928f6Slogin /// @param self Arc<dyn xxx> downcast_arc<T: Any + Send + Sync>(self: Arc<Self>) -> Option<Arc<T>>6577c928f6Slogin fn downcast_arc<T: Any + Send + Sync>(self: Arc<Self>) -> Option<Arc<T>> { 6677c928f6Slogin let x: Arc<dyn Any> = self.as_any_arc(); 6777c928f6Slogin if x.is::<T>() { 6877c928f6Slogin // into_raw不会改变引用计数 6977c928f6Slogin let p = Arc::into_raw(x); 7077c928f6Slogin let new = unsafe { Arc::from_raw(p as *const T) }; 7177c928f6Slogin return Some(new); 7277c928f6Slogin } 7377c928f6Slogin return None; 7477c928f6Slogin } 7577c928f6Slogin } 76