ratatui_kit/
props.rs

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