ratatui_kit/
props.rs

1use ratatui_kit_macros::Props;
2
3/// # Safety
4pub unsafe trait Props: Send + Sync {}
5
6// 用于处理原始指针释放的trait
7// 通过类型擦除实现对未知类型的内存释放
8trait DropRaw {
9    fn drop_raw(&self, raw: *mut ());
10}
11
12// 类型擦除的具体实现
13// 使用PhantomData标记实际类型T
14struct DropRowImpl<T> {
15    _marker: std::marker::PhantomData<T>,
16}
17
18impl<T> DropRaw for DropRowImpl<T> {
19    // 实际执行内存释放的方法
20    // 将原始指针转换为Box后释放
21    fn drop_raw(&self, raw: *mut ()) {
22        unsafe {
23            let _ = Box::from_raw(raw as *mut T);
24        }
25    }
26}
27
28// 类型擦除容器
29// 支持存储任意类型的属性(owned/borrowed)
30// raw: 指向实际数据的原始指针
31// drop: 可选的drop处理函数(对于owned类型)
32// _marker: 生命周期标记
33pub struct AnyProps<'a> {
34    raw: *mut (),
35    drop: Option<Box<dyn DropRaw + 'a>>,
36    _marker: std::marker::PhantomData<&'a mut ()>,
37}
38
39unsafe impl Send for AnyProps<'_> {}
40unsafe impl Sync for AnyProps<'_> {}
41
42impl<'a> AnyProps<'a> {
43    // 创建拥有所有权的AnyProps实例
44    // T: 实现Props trait的类型
45    pub(crate) fn owned<T>(props: T) -> Self
46    where
47        T: Props + 'a,
48    {
49        // 将属性堆分配并转换为原始指针
50        let raw = Box::into_raw(Box::new(props));
51        Self {
52            raw: raw as *mut (),
53            // 保存对应的drop处理实现
54            drop: Some(Box::new(DropRowImpl::<T> {
55                _marker: std::marker::PhantomData,
56            })),
57            _marker: std::marker::PhantomData,
58        }
59    }
60
61    // 创建借用的AnyProps实例
62    // 不持有所有权,不负责内存释放
63    pub(crate) fn borrowed<T: Props>(props: &'a mut T) -> Self {
64        Self {
65            raw: props as *const _ as *mut (),
66            drop: None, // 不负责内存释放
67            _marker: std::marker::PhantomData,
68        }
69    }
70
71    // 创建只读借用版本
72    // drop字段设为None表示不处理内存释放
73    pub(crate) fn borrow(&mut self) -> Self {
74        Self {
75            raw: self.raw,
76            drop: None,
77            _marker: std::marker::PhantomData,
78        }
79    }
80
81    // 不安全的下转型方法(不可变引用)
82    // 调用者必须确保实际类型与T匹配
83    pub(crate) unsafe fn downcast_ref_unchecked<T: Props>(&self) -> &T {
84        unsafe { &*(self.raw as *const T) }
85    }
86
87    // 不安全的下转型方法(可变引用)
88    // 调用者必须确保实际类型与T匹配
89    pub(crate) unsafe fn downcast_mut_unchecked<T: Props>(&mut self) -> &mut T {
90        unsafe { &mut *(self.raw as *mut T) }
91    }
92}
93
94// 实现Drop trait用于资源释放
95impl Drop for AnyProps<'_> {
96    fn drop(&mut self) {
97        // 如果存在drop处理器,执行内存释放
98        if let Some(drop) = self.drop.take() {
99            drop.drop_raw(self.raw);
100        }
101    }
102}
103
104#[derive(Debug, Clone, Default, Props)]
105pub struct NoProps;