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}