toolshed/
lib.rs

1//! # Toolshed
2//!
3//! This crate contains an `Arena` allocator, along with a few common data
4//! structures that can be used in tandem with it.
5//!
6//! For all those times when you need to create a recursively nested tree
7//! of `enum`s and find yourself in pain having to put everything in
8//! `Box`es all the time.
9//!
10//! ## Features
11//!
12//! + Paginated `Arena`: internally preallocates 64KiB _pages_ on the heap and
13//!     allows `Copy` types to be put on that heap.
14//!
15//! + `CopyCell`: virtually identical to `std::cell::Cell` but requires that
16//!     internal types implement `Copy`, and implements `Copy` itself.
17//!
18//! + `List`, `Map` and `Set`: your basic data structures that allocate on the
19//!     `Arena` and use internal mutability via `CopyCell`. Never worry about
20//!     sharing pointers again!
21//!
22//! + `BloomMap` and `BloomSet`: special variants of `Map` and `Set` with a
23//!     very simple but very fast bloom filter. If a map / set is often queried
24//!     for keys / elements it doesn't contain, the bloom filter check will
25//!     reduce the need to do a full tree lookup, greatly increasing performance.
26//!     The overhead compared to a regular `Map` or `Set` is also minimal.
27//!
28//! + All data structures implement expected traits, such as `Debug` or `PartialEq`.
29//!
30//! + Optional **serde** `Serialize` support behind a feature flag.
31//!
32//! ## Example
33//!
34//! ```rust
35//! use toolshed::Arena;
36//! use toolshed::map::Map;
37//!
38//! // Only `Copy` types can be allocated on the `Arena`!
39//! #[derive(Debug, PartialEq, Clone, Copy)]
40//! enum Foo<'arena> {
41//!     Integer(u64),
42//!
43//!     // Recursive enum without `Box`es!
44//!     Nested(&'arena Foo<'arena>),
45//! }
46//!
47//! fn main() {
48//!     // Create a new arena
49//!     let arena = Arena::new();
50//!
51//!     // We allocate first instance of `Foo` in the arena.
52//!     //
53//!     // Please note that the `alloc` method returns a `&mut` reference.
54//!     // Since we want to share our references around, we are going to
55//!     // dereference and re-reference them to immutable ones with `&*`.
56//!     let child: &Foo = &*arena.alloc(Foo::Integer(42));
57//!
58//!     // Next instance of `Foo` will contain the child reference.
59//!     let parent: &Foo = &*arena.alloc(Foo::Nested(child));
60//!
61//!     // Empty map does not allocate
62//!     let map = Map::new();
63//!
64//!     // Inserting stuff in the map requires a reference to the `Arena`.
65//!     // The reference can be shared, since `Arena` uses interior mutability.
66//!     map.insert(&arena, "child", child);
67//!
68//!     // We can put our `map` on the arena as well. Once again we use the `&*`
69//!     // operation to change the reference to be immutable, just to demonstrate
70//!     // that our `Map` implementation is perfectly happy with internal mutability.
71//!     let map: &Map<&str, &Foo> = &*arena.alloc(map);
72//!
73//!     // Each insert allocates a small chunk of data on the arena. Since arena is
74//!     // preallocated on the heap, these inserts are very, very fast.
75//!     //
76//!     // We only have a non-mutable reference to `map` now, however `Map` is also
77//!     // using interior mutability on references to allow exactly this kind of
78//!     // behavior in a safe manner.
79//!     map.insert(&arena, "parent", parent);
80//!
81//!     assert_eq!(map.get("child"), Some(&Foo::Integer(42)));
82//!     assert_eq!(map.get("parent"), Some(&Foo::Nested(&Foo::Integer(42))));
83//!     assert_eq!(map.get("heh"), None);
84//! }
85//!
86//! ```
87
88#![warn(missing_docs)]
89
90// Pull in serde if `impl_serialize` is enabled
91#[cfg(feature = "impl_serialize")]
92use serde;
93
94// Pull in serde_json for testing if `impl_serialize` is enabled
95#[cfg(all(test, feature = "impl_serialize"))]
96use serde_json;
97
98mod cell;
99pub mod map;
100pub mod set;
101pub mod list;
102mod arena;
103mod bloom;
104mod impl_partial_eq;
105mod impl_debug;
106
107#[cfg(feature = "impl_serialize")]
108mod impl_serialize;
109
110pub use self::arena::{Arena, Uninitialized, NulTermStr};
111pub use self::cell::CopyCell;