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, intra_doc_link_resolution_failure, 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;