Skip to main content

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}
74impl Data for () {}
75
76
77type DataPointer = *mut *mut (dyn Any + 'static);
78
79
80/// **In typical usage of this crate, this function should not be called directly.**
81/// 
82pub fn into_raw (boxed: Box<dyn Any>) -> NonNullFREData {
83    let fat = Box::into_raw(boxed);
84    let raw: DataPointer = Box::into_raw(Box::new(fat));
85    unsafe {NonNull::new_unchecked(raw as FREData)}
86}
87
88/// **In typical usage of this crate, this function should not be called directly.**
89/// 
90#[allow(unsafe_op_in_unsafe_fn)]
91pub unsafe fn from_raw (raw: NonNullFREData) -> Box<dyn Any> {
92    let raw = raw.as_ptr() as DataPointer;
93    let fat = Box::from_raw(raw);
94    let boxed = Box::from_raw(*fat);
95    boxed
96}
97
98/// **In typical usage of this crate, this function should not be called directly.**
99/// 
100/// # Safety
101/// 
102/// The returned reference has an unbounded lifetime and is not tied to any input.
103/// Correct and safe usage requires the caller to impose additional lifetime constraints.
104/// 
105#[allow(unsafe_op_in_unsafe_fn)]
106pub unsafe fn ref_from <'a> (raw: NonNullFREData) -> &'a dyn Any {
107    let raw = raw.as_ptr() as DataPointer;
108    let any = &(**raw);
109    any
110}
111
112/// **In typical usage of this crate, this function should not be called directly.**
113/// 
114/// # Safety
115/// 
116/// The returned reference has an unbounded lifetime and is not tied to any input.
117/// Correct and safe usage requires the caller to impose additional lifetime constraints.
118/// 
119#[allow(unsafe_op_in_unsafe_fn)]
120pub unsafe fn mut_from <'a> (raw: NonNullFREData) -> &'a mut dyn Any {
121    let raw = raw.as_ptr() as DataPointer;
122    let any = &mut (**raw);
123    any
124}
125
126/// **In typical usage of this crate, this function should not be called directly.**
127/// 
128#[allow(unsafe_op_in_unsafe_fn)]
129pub unsafe fn drop_from (raw: NonNullFREData) {
130    drop(from_raw(raw));
131}