sashay/lib.rs
1//! # Sashay
2//!
3//! Sashay contains type-erased slices and references that work _kinda_ like `Any`, but not entirely:
4//!
5//! * `&'a T` -> `AnyRef<'a>`
6//! * `&'a mut T` -> `AnyMut<'a>`
7//! * `&'a [T]` -> `AnySliceRef<'a>`
8//! * `&'a mut [T]` -> `AnySliceMut<'a>`
9//!
10//! The big advantage of these types if that you can deal with references and slices of any type without having to resort to generic code. Perhaps more importantly, it allows you to store them in homogeneous containers without having to use trait objects (which is what I originally wrote this for).
11//!
12//! Any of these refs and muts can be constructed by calling `::erase()` on a reference or slice. The erased types are still lifetime-bound, and they also contains a [`TypeId`](https://doc.rust-lang.org/stable/std/any/struct.TypeId.html) to check if any unerasure is valid. Internally the structures hold pointers to the original data.
13//!
14//! You could `AnyRef/Mut` to erase `[T]` slices, but `AnySliceRef/Mut` retain part of the expected API for primitive slices, such as calling `.len()` or `.is_empty()` and providing access to subslices or individual elements.
15//!
16//! As far as I know the library is sound and it passes `cargo miri test`, but outside of personal use it is untested in the wild. I have chatted with people in the [Rust Zulip](https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/Type-erased.20slices/near/318265693) (big thanks to Lokathor, Ben Kimock, Mario Carneiro and scottmcm) to cover edge cases. Feedback is always appreciated.
17//!
18//! And last but not least: don't forget to enjoy your day! ;)
19//!
20//! ## Example
21//!
22//! ```rust
23//! let data : [i32; 3] = [0, 1, 2];
24//!
25//! // Type-erase a slice
26//! let erased = sashay::AnySliceRef::erase(data.as_slice());
27//! assert_eq!(erased.len(), 3);
28//!
29//! // Unerase the whole slice
30//! let unerased = erased.unerase::<i32>().expect("any was not a &[i32]");
31//! assert_eq!(unerased, data.as_slice());
32//!
33//! // Unerase just a single element
34//! assert_eq!(erased.get(2).unwrap().unerase::<i32>(), Some(&2));
35//! ```
36//!
37//! ## Dependencies
38//!
39//! `sashay` is `#![no_std]` and has 0 dependencies.
40
41#![no_std]
42
43mod any_mut;
44mod any_ref;
45mod any_slice_mut;
46mod any_slice_ref;
47mod range;
48
49pub use any_mut::AnyMut;
50pub use any_ref::AnyRef;
51pub use any_slice_mut::AnySliceMut;
52pub use any_slice_ref::AnySliceRef;