1use ratatui_kit_macros::Props;
2
3pub unsafe trait Props: Send + Sync {}
11
12trait DropRaw {
15 fn drop_raw(&self, raw: *mut ());
16}
17
18struct DropRowImpl<T> {
21 _marker: std::marker::PhantomData<T>,
22}
23
24impl<T> DropRaw for DropRowImpl<T> {
25 fn drop_raw(&self, raw: *mut ()) {
28 unsafe {
29 let _ = Box::from_raw(raw as *mut T);
30 }
31 }
32}
33
34pub struct AnyProps<'a> {
40 raw: *mut (),
41 drop: Option<Box<dyn DropRaw + 'a>>,
42 _marker: std::marker::PhantomData<&'a mut ()>,
43}
44
45unsafe impl Send for AnyProps<'_> {}
46unsafe impl Sync for AnyProps<'_> {}
47
48impl<'a> AnyProps<'a> {
49 pub(crate) fn owned<T>(props: T) -> Self
52 where
53 T: Props + 'a,
54 {
55 let raw = Box::into_raw(Box::new(props));
57 Self {
58 raw: raw as *mut (),
59 drop: Some(Box::new(DropRowImpl::<T> {
61 _marker: std::marker::PhantomData,
62 })),
63 _marker: std::marker::PhantomData,
64 }
65 }
66
67 pub(crate) fn borrowed<T: Props>(props: &'a mut T) -> Self {
70 Self {
71 raw: props as *const _ as *mut (),
72 drop: None, _marker: std::marker::PhantomData,
74 }
75 }
76
77 pub(crate) fn borrow(&mut self) -> Self {
80 Self {
81 raw: self.raw,
82 drop: None,
83 _marker: std::marker::PhantomData,
84 }
85 }
86
87 pub(crate) unsafe fn downcast_ref_unchecked<T: Props>(&self) -> &T {
90 unsafe { &*(self.raw as *const T) }
91 }
92
93 pub(crate) unsafe fn downcast_mut_unchecked<T: Props>(&mut self) -> &mut T {
96 unsafe { &mut *(self.raw as *mut T) }
97 }
98}
99
100impl Drop for AnyProps<'_> {
102 fn drop(&mut self) {
103 if let Some(drop) = self.drop.take() {
105 drop.drop_raw(self.raw);
106 }
107 }
108}
109
110#[derive(Debug, Clone, Default, Props)]
111pub struct NoProps;