1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

use std::any::{TypeId, Any};

/// ## Anonymous Type 
/// 
/// Emulates dynamic typing for efficient, albeit unsafe, data storage.  
///
/// Internally, Anon is a `Vec<u8>`. It works by casting a type to 
/// a slice and adding it to the vector.  The inner value can then be downcasted to either
/// a &mut T or a &T. 
/// 
/// ## Safety Disclaimer
/// 
/// Use of Anon is inherently unsafe! Attempting to access and modify the data CAN
/// cause major problems.  Be careful!
/// 
/// Any structs that are allocated to Anon should have `#[repr(C)]` to ensure
/// consistent alignment.  Failure to do so may cause the data to be come garbled. 
/// 
/// ## Usage
/// 
/// Anon provides methods for construction either in-place with a value or 
/// uninit for later initialization.
/// 
/// ```
/// use anon_vec::Anon;
/// 
/// // in-place construction
/// let x: i32 = 5;
/// let mut anon = Anon::new::<i32>(x);
/// 
/// // access the inner value with `cast_ref` and `cast_mut`
/// let v: &i32 = anon.cast_ref::<i32>();
/// let v: &mut i32 = anon.cast_mut::<i32>();
/// 
/// // uninit construction, to be initialized later. 
/// let mut anon = Anon::uninit();
/// 
/// ```
pub struct Anon {
    /// The Value, represented as a `Vec<u8>`.
    /// 
    /// To make this possible, cast the value to a slice, then
    /// copy it into `inner`.  This is very unsafe, but it allows
    /// for dynamic typing in data storage systems like game engines.
    inner: Vec<u8>,

    /// The TypeId of the value stored in this Anon. 
    /// Can be used to check for cast validity.
    typeid: TypeId,
}

impl Anon {

    // --- // Initializers // --- //

    /// Creates a new Anonymous Type in-place.
    /// 
    /// ## Usage
    /// ```
    /// use anon_vec::Anon;
    /// 
    /// let x: i32 = 5;
    /// let anon = Anon::new::<i32>(x);
    /// ```
    /// ## Memory Safety
    /// 
    /// Anon will consume the value on `Anon::init` or `Anon::new`, so the value
    /// will inherit the lifetime of Anon, allowing you to store `Vec<T>` as anon safely. 
    pub fn new<T>(val: T) -> Self 
    where
        T: Any + 'static,
    {
        let mut inner: Vec<u8> = (0..std::mem::size_of::<T>()).map(|_| 0).collect();

        let ptr = inner.as_mut_ptr() as *mut T;
        unsafe { *(ptr) = val; }

        Self {
            inner, typeid: TypeId::of::<T>(),
        }
    }

    /// Creates a new Anonymous Type in-place from a *const u8 which represents T.
    pub fn from_ptr(ptr: *const u8, size: usize, typeid: TypeId) -> Self {
        Self {
            inner: Vec::from_iter((0..size).map(|i| unsafe { *(ptr.add(i)) })),
            typeid,
        }
    }

    /// Creates a new, uninitialized Anonymous Type. 
    /// 
    /// ## Usage
    /// ```
    /// use anon_vec::Anon;
    /// 
    /// // declare the wrapper
    /// let mut anon = Anon::uninit();
    /// 
    /// // initialize later
    /// let x: i32 = 5;
    /// anon.init::<i32>(x);
    /// ```
    /// 
    /// ## Memory Safety
    /// 
    /// Anon will consume the value on `Anon::init` or `Anon::new`, so the value
    /// will inherit the lifetime of Anon, allowing you to store `Vec<T>` as anon safely. 
    /// 
    /// If you try and access an uninitialized Anon, you will access memory incorrectly.
    pub fn uninit() -> Self {
        Self {
            inner: Vec::new(),
            typeid: TypeId::of::<i32>(),
        }
    }

    /// Initializes an Anon created with Anon::uninit().
    /// 
    /// ## Usage
    /// ```
    /// use anon_vec::Anon;
    /// 
    /// // declare the wrapper
    /// let mut anon = Anon::uninit();
    /// 
    /// // initialize later
    /// let x: i32 = 5;
    /// anon.init::<i32>(x);
    /// ```
    /// 
    /// ## Memory Safety
    /// 
    /// Anon will consume the value on `Anon::init` or `Anon::new`, so the value
    /// will inherit the lifetime of Anon, allowing you to store `Vec<T>` as anon safely. 
    pub fn init<T>(&mut self, val: T) 
    where
        T: Any + 'static,
    {
        // extend the vector by the size of T, filling with 0s. 
        self.inner.extend((0..std::mem::size_of::<T>()).map(|_| 0));
        // cast the *mut u8 to *mut T (which we can do because T is 'static and *mut u8 is the same size)
        let ptr = self.inner.as_mut_ptr() as *mut T;
        // dereference ptr and assign it to the value
        unsafe { *(ptr) = val; }
        // assign the typeid correctly.
        self.typeid = TypeId::of::<T>();
    }

    // --- // Accessors // --- //

    pub fn inner(self) -> Vec<u8> {
        self.inner
    }

    /// The Size of this Anon, in bytes. 
    pub fn size(&self) -> usize {
        self.inner.len()
    }

    /// Returns the TypeId of the types this anon stores.
    /// Will return `TypeId::of::<i32>()` if uninit.
    pub fn typeid(&self) -> TypeId {
        self.typeid
    }

    /// Get a slice that points to the inner value.
    pub fn as_slice(&self) -> &[u8] {
        self.inner.as_slice()
    }

    /// Get a mutable slice that points to the inner value.
    pub fn as_mut_slice(&mut self) -> &mut [u8] {
        self.inner.as_mut_slice()
    }

    /// Check whether or not the inner value is empty, or uninit. 
    pub fn is_uninit(&self) -> bool {
        self.inner.is_empty()
    }

    /// Cast the inner value to T.
    /// 
    /// Inernally, the inner value is Vec<u8>. To access, the
    /// *mut u8 inside the vec is cast to *const T and returned. 
    /// 
    /// ## Usage
    /// ```
    /// use anon_vec::Anon;
    /// 
    /// let x: i32 = 5;
    /// let anon = Anon::new(x);
    /// 
    /// let v: &i32 = anon.cast_ref::<i32>();
    /// ```
    pub fn cast_ref<T>(&self) -> &T
    where
        T: Any + 'static,
    {
        unsafe { &*(self.inner.as_ptr() as *const T) }
    }

    /// Cast the inner value to T.
    /// 
    /// Inernally, the inner value is Vec<u8>. To access, the
    /// *mut u8 inside the vec is cast to *mut T and returned. 
    /// 
    /// ## Usage
    /// ```
    /// use anon_vec::Anon;
    /// 
    /// let x: i32 = 5;
    /// let mut anon = Anon::new(x);
    /// 
    /// let v: &mut i32 = anon.cast_mut::<i32>();
    /// ```
    pub fn cast_mut<T>(&mut self) -> &mut T
    where
        T: Any + 'static,
    {
        unsafe { &mut *(self.inner.as_mut_ptr() as *mut T) }
    }

    /// Consume the Anon, returning the inner value as T.
    /// 
    /// ## Usage
    /// ```
    /// use anon_vec::Anon;
    /// let x: i32 = 5;
    /// let mut anon = Anon::new(x);
    /// 
    /// let v: i32 = anon.consume::<i32>();
    /// ```
    pub fn consume<T>(self) -> T
    where
        T: Any + Clone + 'static,
    {
        let out = unsafe { &*(self.inner.as_ptr() as *const T) };
        out.clone()
    }
}

#[cfg(test)]
mod tests {

    use crate::anon::Anon;

    #[repr(C)]
    #[derive(PartialEq, Debug, Clone)]
    struct Thing {
        pub a: i32,
        pub b: i32,
        pub c: i32,
    }

    impl Thing {
        fn new(a: i32, b: i32, c: i32) -> Self {
            Self { a, b, c }
        }

        fn sum(&self) -> i32 {
            self.a + self.b + self.c
        }
    }

    #[test]
    fn new() {
        let t = Thing::new(1, 2, 3);

        let anon = Anon::new(t);

        let thing = anon.cast_ref::<Thing>();

        assert_eq!(6, thing.sum());
    }

    #[test]
    fn uninit_init() {
        let mut anon = Anon::uninit();

        {
            let t = Thing::new(1, 2, 3);

            anon.init::<Thing>(t);
        }

        let thing = anon.cast_ref::<Thing>();

        assert_eq!(6, thing.sum());
    }

    #[test]
    fn vec() {
        let mut anon = Anon::uninit();

        {
            let t = 
                vec![
                    Thing::new(1, 2, 3),
                    Thing::new(1, 2, 3),
                    Thing::new(1, 2, 3),
                ];

            anon.init::<Vec<Thing>>(t);
        }

        let things = anon.cast_ref::<Vec<Thing>>();

        let v = things[0].sum() + things[1].sum() + things[2].sum();

        assert_eq!(v, 18);
    }

    #[test]
    fn consume() {
        let mut anon = Anon::uninit();

        {
            let t = 
                vec![
                    Thing::new(1, 2, 3),
                    Thing::new(1, 2, 3),
                    Thing::new(1, 2, 3),
                ];

            anon.init::<Vec<Thing>>(t);
        }

        let things = anon.consume::<Vec<Thing>>();

        let v = things[0].sum() + things[1].sum() + things[2].sum();

        assert_eq!(v, 18);
    }
}