1use ratatui_kit_macros::Props;
2
3pub unsafe trait Props: Send + Sync {}
5
6trait DropRaw {
9 fn drop_raw(&self, raw: *mut ());
10}
11
12struct DropRowImpl<T> {
15 _marker: std::marker::PhantomData<T>,
16}
17
18impl<T> DropRaw for DropRowImpl<T> {
19 fn drop_raw(&self, raw: *mut ()) {
22 unsafe {
23 let _ = Box::from_raw(raw as *mut T);
24 }
25 }
26}
27
28pub 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 pub(crate) fn owned<T>(props: T) -> Self
46 where
47 T: Props + 'a,
48 {
49 let raw = Box::into_raw(Box::new(props));
51 Self {
52 raw: raw as *mut (),
53 drop: Some(Box::new(DropRowImpl::<T> {
55 _marker: std::marker::PhantomData,
56 })),
57 _marker: std::marker::PhantomData,
58 }
59 }
60
61 pub(crate) fn borrowed<T: Props>(props: &'a mut T) -> Self {
64 Self {
65 raw: props as *const _ as *mut (),
66 drop: None, _marker: std::marker::PhantomData,
68 }
69 }
70
71 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 pub(crate) unsafe fn downcast_ref_unchecked<T: Props>(&self) -> &T {
84 unsafe { &*(self.raw as *const T) }
85 }
86
87 pub(crate) unsafe fn downcast_mut_unchecked<T: Props>(&mut self) -> &mut T {
90 unsafe { &mut *(self.raw as *mut T) }
91 }
92}
93
94impl Drop for AnyProps<'_> {
96 fn drop(&mut self) {
97 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;