anon_vec/
anon.rs

1
2use std::any::{TypeId, Any};
3
4/// ## Anonymous Type 
5/// 
6/// Emulates dynamic typing for efficient, albeit unsafe, data storage.  
7///
8/// Internally, Anon is a `Vec<u8>`. It works by casting a type to 
9/// a slice and adding it to the vector.  The inner value can then be downcasted to either
10/// a &mut T or a &T. 
11/// 
12/// ## Safety Disclaimer
13/// 
14/// Use of Anon is inherently unsafe! Attempting to access and modify the data CAN
15/// cause major problems.  Be careful!
16/// 
17/// Any structs that are allocated to Anon should have `#[repr(C)]` to ensure
18/// consistent alignment.  Failure to do so may cause the data to be come garbled. 
19/// 
20/// ## Usage
21/// 
22/// Anon provides methods for construction either in-place with a value or 
23/// uninit for later initialization.
24/// 
25/// ```
26/// use anon_vec::Anon;
27/// 
28/// // in-place construction
29/// let x: i32 = 5;
30/// let mut anon = Anon::new::<i32>(x);
31/// 
32/// // access the inner value with `cast_ref` and `cast_mut`
33/// let v: &i32 = anon.cast_ref::<i32>();
34/// let v: &mut i32 = anon.cast_mut::<i32>();
35/// 
36/// // uninit construction, to be initialized later. 
37/// let mut anon = Anon::uninit();
38/// 
39/// ```
40pub struct Anon {
41    /// The Value, represented as a `Vec<u8>`.
42    /// 
43    /// To make this possible, cast the value to a slice, then
44    /// copy it into `inner`.  This is very unsafe, but it allows
45    /// for dynamic typing in data storage systems like game engines.
46    inner: Vec<u8>,
47
48    /// The TypeId of the value stored in this Anon. 
49    /// Can be used to check for cast validity.
50    typeid: TypeId,
51}
52
53impl Anon {
54
55    // --- // Initializers // --- //
56
57    /// Creates a new Anonymous Type in-place.
58    /// 
59    /// ## Usage
60    /// ```
61    /// use anon_vec::Anon;
62    /// 
63    /// let x: i32 = 5;
64    /// let anon = Anon::new::<i32>(x);
65    /// ```
66    /// ## Memory Safety
67    /// 
68    /// Anon will consume the value on `Anon::init` or `Anon::new`, so the value
69    /// will inherit the lifetime of Anon, allowing you to store `Vec<T>` as anon safely. 
70    pub fn new<T>(val: T) -> Self 
71    where
72        T: Any + 'static,
73    {
74        let mut inner: Vec<u8> = (0..std::mem::size_of::<T>()).map(|_| 0).collect();
75
76        let ptr = inner.as_mut_ptr() as *mut T;
77        unsafe { *(ptr) = val; }
78
79        Self {
80            inner, typeid: TypeId::of::<T>(),
81        }
82    }
83
84    /// Creates a new Anonymous Type in-place from a *const u8 which represents T.
85    pub fn from_ptr(ptr: *const u8, size: usize, typeid: TypeId) -> Self {
86        Self {
87            inner: Vec::from_iter((0..size).map(|i| unsafe { *(ptr.add(i)) })),
88            typeid,
89        }
90    }
91
92    /// Creates a new, uninitialized Anonymous Type. 
93    /// 
94    /// ## Usage
95    /// ```
96    /// use anon_vec::Anon;
97    /// 
98    /// // declare the wrapper
99    /// let mut anon = Anon::uninit();
100    /// 
101    /// // initialize later
102    /// let x: i32 = 5;
103    /// anon.init::<i32>(x);
104    /// ```
105    /// 
106    /// ## Memory Safety
107    /// 
108    /// Anon will consume the value on `Anon::init` or `Anon::new`, so the value
109    /// will inherit the lifetime of Anon, allowing you to store `Vec<T>` as anon safely. 
110    /// 
111    /// If you try and access an uninitialized Anon, you will access memory incorrectly.
112    pub fn uninit() -> Self {
113        Self {
114            inner: Vec::new(),
115            typeid: TypeId::of::<i32>(),
116        }
117    }
118
119    /// Initializes an Anon created with Anon::uninit().
120    /// 
121    /// ## Usage
122    /// ```
123    /// use anon_vec::Anon;
124    /// 
125    /// // declare the wrapper
126    /// let mut anon = Anon::uninit();
127    /// 
128    /// // initialize later
129    /// let x: i32 = 5;
130    /// anon.init::<i32>(x);
131    /// ```
132    /// 
133    /// ## Memory Safety
134    /// 
135    /// Anon will consume the value on `Anon::init` or `Anon::new`, so the value
136    /// will inherit the lifetime of Anon, allowing you to store `Vec<T>` as anon safely. 
137    pub fn init<T>(&mut self, val: T) 
138    where
139        T: Any + 'static,
140    {
141        // extend the vector by the size of T, filling with 0s. 
142        self.inner.extend((0..std::mem::size_of::<T>()).map(|_| 0));
143        // cast the *mut u8 to *mut T (which we can do because T is 'static and *mut u8 is the same size)
144        let ptr = self.inner.as_mut_ptr() as *mut T;
145        // dereference ptr and assign it to the value
146        unsafe { *(ptr) = val; }
147        // assign the typeid correctly.
148        self.typeid = TypeId::of::<T>();
149    }
150
151    // --- // Accessors // --- //
152
153    pub fn inner(self) -> Vec<u8> {
154        self.inner
155    }
156
157    /// The Size of this Anon, in bytes. 
158    pub fn size(&self) -> usize {
159        self.inner.len()
160    }
161
162    /// Returns the TypeId of the types this anon stores.
163    /// Will return `TypeId::of::<i32>()` if uninit.
164    pub fn typeid(&self) -> TypeId {
165        self.typeid
166    }
167
168    /// Get a slice that points to the inner value.
169    pub fn as_slice(&self) -> &[u8] {
170        self.inner.as_slice()
171    }
172
173    /// Get a mutable slice that points to the inner value.
174    pub fn as_mut_slice(&mut self) -> &mut [u8] {
175        self.inner.as_mut_slice()
176    }
177
178    /// Check whether or not the inner value is empty, or uninit. 
179    pub fn is_uninit(&self) -> bool {
180        self.inner.is_empty()
181    }
182
183    /// Cast the inner value to T.
184    /// 
185    /// Inernally, the inner value is Vec<u8>. To access, the
186    /// *mut u8 inside the vec is cast to *const T and returned. 
187    /// 
188    /// ## Usage
189    /// ```
190    /// use anon_vec::Anon;
191    /// 
192    /// let x: i32 = 5;
193    /// let anon = Anon::new(x);
194    /// 
195    /// let v: &i32 = anon.cast_ref::<i32>();
196    /// ```
197    pub fn cast_ref<T>(&self) -> &T
198    where
199        T: Any + 'static,
200    {
201        unsafe { &*(self.inner.as_ptr() as *const T) }
202    }
203
204    /// Cast the inner value to T.
205    /// 
206    /// Inernally, the inner value is Vec<u8>. To access, the
207    /// *mut u8 inside the vec is cast to *mut T and returned. 
208    /// 
209    /// ## Usage
210    /// ```
211    /// use anon_vec::Anon;
212    /// 
213    /// let x: i32 = 5;
214    /// let mut anon = Anon::new(x);
215    /// 
216    /// let v: &mut i32 = anon.cast_mut::<i32>();
217    /// ```
218    pub fn cast_mut<T>(&mut self) -> &mut T
219    where
220        T: Any + 'static,
221    {
222        unsafe { &mut *(self.inner.as_mut_ptr() as *mut T) }
223    }
224
225    /// Consume the Anon, returning the inner value as T.
226    /// 
227    /// ## Usage
228    /// ```
229    /// use anon_vec::Anon;
230    /// let x: i32 = 5;
231    /// let mut anon = Anon::new(x);
232    /// 
233    /// let v: i32 = anon.consume::<i32>();
234    /// ```
235    pub fn consume<T>(self) -> T
236    where
237        T: Any + Clone + 'static,
238    {
239        let out = unsafe { &*(self.inner.as_ptr() as *const T) };
240        out.clone()
241    }
242}
243
244#[cfg(test)]
245mod tests {
246
247    use crate::anon::Anon;
248
249    #[repr(C)]
250    #[derive(PartialEq, Debug, Clone)]
251    struct Thing {
252        pub a: i32,
253        pub b: i32,
254        pub c: i32,
255    }
256
257    impl Thing {
258        fn new(a: i32, b: i32, c: i32) -> Self {
259            Self { a, b, c }
260        }
261
262        fn sum(&self) -> i32 {
263            self.a + self.b + self.c
264        }
265    }
266
267    #[test]
268    fn new() {
269        let t = Thing::new(1, 2, 3);
270
271        let anon = Anon::new(t);
272
273        let thing = anon.cast_ref::<Thing>();
274
275        assert_eq!(6, thing.sum());
276    }
277
278    #[test]
279    fn uninit_init() {
280        let mut anon = Anon::uninit();
281
282        {
283            let t = Thing::new(1, 2, 3);
284
285            anon.init::<Thing>(t);
286        }
287
288        let thing = anon.cast_ref::<Thing>();
289
290        assert_eq!(6, thing.sum());
291    }
292
293    #[test]
294    fn vec() {
295        let mut anon = Anon::uninit();
296
297        {
298            let t = 
299                vec![
300                    Thing::new(1, 2, 3),
301                    Thing::new(1, 2, 3),
302                    Thing::new(1, 2, 3),
303                ];
304
305            anon.init::<Vec<Thing>>(t);
306        }
307
308        let things = anon.cast_ref::<Vec<Thing>>();
309
310        let v = things[0].sum() + things[1].sum() + things[2].sum();
311
312        assert_eq!(v, 18);
313    }
314
315    #[test]
316    fn consume() {
317        let mut anon = Anon::uninit();
318
319        {
320            let t = 
321                vec![
322                    Thing::new(1, 2, 3),
323                    Thing::new(1, 2, 3),
324                    Thing::new(1, 2, 3),
325                ];
326
327            anon.init::<Vec<Thing>>(t);
328        }
329
330        let things = anon.consume::<Vec<Thing>>();
331
332        let v = things[0].sum() + things[1].sum() + things[2].sum();
333
334        assert_eq!(v, 18);
335    }
336}