fre_rs/data.rs
1//!
2//! This module provides safe conversions between concrete typed instances
3//! and raw pointers for native data.
4//!
5//! [`Box<dyn Any>`] is a fat pointer stored on the stack. Casting it directly
6//! to a raw pointer will truncate its metadata. To preserve type information,
7//! the fat pointer must be stored intact on the heap, so it can be safely
8//! reconstructed from a raw pointer.
9//!
10
11
12use super::*;
13
14
15pub(crate) type ExtensionData = Arc<Mutex<Box<dyn Any>>>;
16impl Data for ExtensionData {}
17
18
19/// Should be implemented for all native data types to ensure safe pointer passing
20/// and correct memory management. Native data includes Extension Data, Context Data,
21/// and Function data.
22///
23pub trait Data: 'static + Sized {
24 fn into_boxed (self) -> Box<dyn Any> {
25 Box::new(self) as Box<dyn Any>
26 }
27
28 fn from_boxed (boxed: Box<dyn Any>) -> Result<Self, Box<dyn Any>> {
29 boxed.downcast()
30 .map(|b| *b)
31 .map_err(|b| b)
32 }
33
34 /// **In typical usage of this crate, this function should not be called directly.**
35 ///
36 fn into_raw (self) -> NonNullFREData {
37 super::data::into_raw(self.into_boxed())
38 }
39
40 /// **In typical usage of this crate, this function should not be called directly.**
41 ///
42 #[allow(unsafe_op_in_unsafe_fn)]
43 unsafe fn from_raw (raw: NonNullFREData) -> Self {
44 let boxed = super::data::from_raw(raw);
45 Self::from_boxed(boxed).unwrap()
46 }
47
48 /// **In typical usage of this crate, this function should not be called directly.**
49 ///
50 /// # Safety
51 ///
52 /// The returned reference has an unbounded lifetime and is not tied to any input.
53 /// Correct and safe usage requires the caller to impose additional lifetime constraints.
54 ///
55 #[allow(unsafe_op_in_unsafe_fn)]
56 unsafe fn ref_from <'a> (raw: NonNullFREData) -> Result<&'a Self, &'a dyn Any> {
57 let any = super::data::ref_from(raw);
58 any.downcast_ref().ok_or(any)
59 }
60
61 /// **In typical usage of this crate, this function should not be called directly.**
62 ///
63 /// # Safety
64 ///
65 /// The returned reference has an unbounded lifetime and is not tied to any input.
66 /// Correct and safe usage requires the caller to impose additional lifetime constraints.
67 ///
68 #[allow(unsafe_op_in_unsafe_fn)]
69 unsafe fn mut_from <'a> (raw: NonNullFREData) -> Result<&'a mut Self, &'a mut dyn Any> {
70 let fat = super::data::mut_from(raw) as *mut dyn Any;
71 (&mut (*fat)).downcast_mut().ok_or(&mut (*fat))
72 }
73}
74
75
76type DataPointer = *mut *mut (dyn Any + 'static);
77
78
79/// **In typical usage of this crate, this function should not be called directly.**
80///
81pub fn into_raw (boxed: Box<dyn Any>) -> NonNullFREData {
82 let fat = Box::into_raw(boxed);
83 let raw: DataPointer = Box::into_raw(Box::new(fat));
84 unsafe {NonNull::new_unchecked(raw as FREData)}
85}
86
87/// **In typical usage of this crate, this function should not be called directly.**
88///
89#[allow(unsafe_op_in_unsafe_fn)]
90pub unsafe fn from_raw (raw: NonNullFREData) -> Box<dyn Any> {
91 let raw = raw.as_ptr() as DataPointer;
92 let fat = Box::from_raw(raw);
93 let boxed = Box::from_raw(*fat);
94 boxed
95}
96
97/// **In typical usage of this crate, this function should not be called directly.**
98///
99/// # Safety
100///
101/// The returned reference has an unbounded lifetime and is not tied to any input.
102/// Correct and safe usage requires the caller to impose additional lifetime constraints.
103///
104#[allow(unsafe_op_in_unsafe_fn)]
105pub unsafe fn ref_from <'a> (raw: NonNullFREData) -> &'a dyn Any {
106 let raw = raw.as_ptr() as DataPointer;
107 let any = &(**raw);
108 any
109}
110
111/// **In typical usage of this crate, this function should not be called directly.**
112///
113/// # Safety
114///
115/// The returned reference has an unbounded lifetime and is not tied to any input.
116/// Correct and safe usage requires the caller to impose additional lifetime constraints.
117///
118#[allow(unsafe_op_in_unsafe_fn)]
119pub unsafe fn mut_from <'a> (raw: NonNullFREData) -> &'a mut dyn Any {
120 let raw = raw.as_ptr() as DataPointer;
121 let any = &mut (**raw);
122 any
123}
124
125/// **In typical usage of this crate, this function should not be called directly.**
126///
127#[allow(unsafe_op_in_unsafe_fn)]
128pub unsafe fn drop_from (raw: NonNullFREData) {
129 drop(from_raw(raw));
130}