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