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
//! Anonymous Types and Anonymously Typed Vectors for Dynamic Type Emulation in Rust.
//!
//! anon_vec is essentially an easier-to-use replacement for Box<dyn Any>, without
//! the safety checks that come along with Box<dyn Any>. It was created for strata-ecs
//! with the goal of storing Components in AnonVecs.
//!
//! ## Memory Safety
//!
//! Usage of Anon, AnonVec, and AnonVec Iterators is inherently unsafe and should be used with
//! caution. Attempting to access these types incorrectly can result in data leaks, incorrect
//! values, and invalid memory access, leading to catastrophic errors.
//!
//! Although it may sometime in the future, anon_vec does not currently implement
//! any error checking. You are expected to make good decisions about managing the unsafety
//! of these types.
//!
//! ## Usage
//!
//! Use this Crate if you need Dynamic Typing and are ok with some unsafe code.
//!
//! anon_vec supports Anonymous single-types called [`Anon`]. These types are
//! useful for moving data around in your engine, and the inner value can only be accessed
//! in a scope where the type is known (`T`).
//!
//! ```
//! use anon_vec::Anon;
//! use std::mem::size_of;
//! use std::any::TypeId;
//!
//! // you can create anons from existing values...
//! let x: i32 = 5;
//! let mut anon1 = Anon::new::<i32>(x);
//!
//! // the value within can then be accessed.
//! let y: &i32 = anon1.cast_ref::<i32>();
//! let z: &i32 = anon1.cast_ref::<i32>();
//!
//! // Anons can also be uninitialized.
//! let mut anon2 = Anon::uninit();
//!
//! if anon2.is_uninit() {
//! anon2.init::<i32>(5);
//! } else {
//! // do something to the value
//! }
//! ```
//!
//! anon_vec supports Anonymous Vectors called [`AnonVec`]. This type is useful when you
//! want to store a Vec<T>, but you don't know T at compile-time. AnonVec converts T to u8, allowing
//! for sequential storage of T with minimal heap allocation. AnonVec can be accessed either with T,
//! or by converting the value to Anon.
//!
//! ```
//! use anon_vec::AnonVec;
//! use anon_vec::Anon;
//! use std::mem::size_of;
//! use std::any::TypeId;
//!
//! // You can create AnonVecs from a T...
//! let mut anon1 = AnonVec::new::<i32>();
//!
//! // ...or from a size.
//! let mut anon2 = AnonVec::from_size(size_of::<i32>(), TypeId::of::<i32>());
//!
//! // values can be pushed to the vec.
//! anon1.push::<i32>(5);
//! anon1.push::<i32>(5);
//!
//! // and removed.
//! anon1.remove(1);
//!
//! // AnonVecs can also be uninitialized
//! let mut anon3 = Anon::uninit();
//!
//! if anon3.is_uninit() {
//! anon3.init::<i32>(5);
//! } else {
//! // do something to the value.
//! }
//! ```
//!
//! anon_vec supports typed iterators over [`AnonVec`], and chaining iterators together.
//! This is particularly useful for ECS, and the motivation behind why chaining iterators were included.
//!
//! ['AnonIter'] can be created with AnonVec::iter::<T>(). It takes a pointer to the inner value of
//! [`AnonIter`] and is not lifetime-checked. If the Iter outlives its parent AnonVec, iterating it will
//! access invalid data.
//!
//! [`AnonIterMut`] is the same as AnonIter, and can be created with AnonVec::iter_mut::<T>().
//!
//! [`AnonChain`] and [`AnonChainMut`] use the push method to construct a chain of iterators that can be
//! iterated as one.
#![allow(dead_code)]
mod anon;
mod iter;
mod vec;
pub use anon::Anon;
pub use vec::AnonVec;
pub use iter::{
AnonChainMut,
AnonChain,
AnonIter,
AnonIterMut,
};