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
//! An implementation of SlotMap with minimal restrictions on Keys and Values
//!
//! This is an implementation of the slot map data structure similar to
//! [SlotMap](https://github.com/orlp/slotmap) with fewer restrictions and the
//! ability to embed data inside the key objects. The "one-way" moniker for
//! this crate comes from an implementation detail that prevent inserted values
//! from being taken out again unless they are replaced with another instance.
//! Values that are inserted can be referenced, and written to, but ownership of
//! the values remains with the map even after the value is "removed".
//!
//! The data structure uses fixed size chunks (like
//! [SlotMap's DenseSlotMap](https://docs.rs/slotmap/0.4.0/slotmap/dense/struct.DenseSlotMap.html)),
//! so lookups require 2 steps of indirection.
//!
//! # Example Usage:
//! First create a Key Class with an embedded data type
//!
//! ```
//! use one_way_slot_map::*;
//!
//! // Define a simple key with an embedded usize
//! define_key_type!(DemoKey<usize>);
//!
//! // Or define a less-simple key with some derived traits
//! define_key_type!(TestKeyWithDerives<usize> : Copy + Clone + Debug);
//!
//! //Then create a slot map and use the key for crud operations
//! let mut slot_map = SlotMap::new();
//!
//! let key: DemoKey = slot_map.insert(0, "Demo!");
//! assert_eq!(Some(&"Demo!"), slot_map.get(&key));
//! let slot = slot_map.get_mut(&key).unwrap();
//! *slot = "Updated!";
//!
//! assert_eq!(Some(&mut "Updated!"), slot_map.remove(&key));
//! assert_eq!(None, slot_map.get(&key));
//! ```
#![warn(
missing_docs,
rust_2018_idioms,
missing_debug_implementations,
rustdoc::broken_intra_doc_links,
clippy::all
)]
#[macro_use]
#[cfg(test)]
extern crate static_assertions;
/// Macro for creating a simple Key type for one-way slot maps. Key types can be
/// created from scratch, but for most cases, this will produce what you want
#[macro_export]
macro_rules! define_key_type (
($visability:vis $key_type:ident<$pointer_type:ty> $(: $derive_1:ident $(+ $more_derives:ident)* )?) => {
$(#[derive($derive_1 $(, $more_derives)*)])?
$visability struct $key_type {
pub pointer: $pointer_type,
slot_key: one_way_slot_map::SlotMapKeyData,
}
impl std::borrow::Borrow<one_way_slot_map::SlotMapKeyData> for $key_type {
fn borrow(&self) -> &one_way_slot_map::SlotMapKeyData {
&self.slot_key
}
}
impl From<($pointer_type, one_way_slot_map::SlotMapKeyData)> for $key_type {
fn from(f: ($pointer_type, one_way_slot_map::SlotMapKeyData)) -> Self {
let (pointer, slot_key) = f;
$key_type { pointer, slot_key }
}
}
impl one_way_slot_map::SlotMapKey<$pointer_type> for $key_type {}
};
);
/// This tells the size of the chunks used by the slot map. I'm not sure why
/// or how this would be used, but maybe it's good to know
pub const SLOT_MAP_CHUNK_SIZE: usize = 256;
pub use slot_map::SlotMap;
pub use slot_map_key::SlotMapKey;
pub use slot_map_key_data::SlotMapKeyData;
// pub use slot_map_value_iterator::SlotMapValueIterator;
mod slot_map;
mod slot_map_key;
mod slot_map_key_data;
// mod slot_map_value_iterator;