casting.rs 2.3 KB

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