prefix_array/
lib.rs

1// STOP! Are you trying to read this crates source code?
2//
3// shared.rs contains the primary implementations of PrefixArray* and *SubSlice in a trait form.
4// Its done this way so that PrefixArray can be a Vec<(K, V)> and PrefixArraySet can be a Vec<K>,
5// instead of having PrefixArraySet be a PrefixArray<K, ()> under the hood (this allows some extra
6// safe guarantees like being able to expose &[K] safely in public apis).
7//
8// Unsafe code worth auditing is in shared/vec_ext.rs, which houses the only significant unsafe
9// code in the crate (and is the only place where a safety bug could potentially be, as other
10// unsafe uses are trivial).
11//
12// map.rs and set.rs contain public api and public impls for PrefixArray/Set and Set/SubSlice
13// while the associated (map|set)/iter.rs contains boilerplate for the iterators they implement.
14//
15// Most test cases live in map.rs where they are tested against the public api of PrefixArray, as
16// it shares logic with PrefixArraySet; if it is correct PrefixArraySet (a subset of it) should also
17// be correct. We do need more test cases to comprehensively prove some behaviours still.
18//
19#![no_std]
20#![warn(clippy::alloc_instead_of_core, clippy::std_instead_of_alloc)]
21#![warn(clippy::pedantic, clippy::cargo)]
22#![allow(clippy::module_name_repetitions)]
23#![warn(missing_docs, clippy::missing_docs_in_private_items)]
24//! `prefix_array` is a crate consisting of datastructures that aid in querying data based on prefixes of string keys,
25//!  the main feature being searching and refining on subgroups with common prefixes.
26//!
27//!  Use [`PrefixArray`] when you want a HashMap-like structure, and [`PrefixArraySet`] for a HashSet-like structure.
28//!
29//! ## Creating a PrefixArray(Set)
30//! For creating a new collection, ideally you can use the `FromIterator` implementation, this has `O(n log n)` complexity and with an `ExactSizeIterator` will allocate once.
31//!  If you cannot use `FromIterator` it is recommended to use `PrefixArray(Set)::from_vec_lossy` instead, as this is what `FromIterator` calls under the hood.
32//!
33//! It is ill advised to use `insert` in a loop to create a `PrefixArray(Set)`, as this has `O(n^2)` complexity.
34//!
35//! For an already partially filled `PrefixArray(Set)` that you wish to insert multiple items into, consider the `Extend` implementation, which is specifically designed for this purpose.
36//!
37//! If you have a partially filled `PrefixArray(Set)` and need to call `Extend` multiple times, but
38//! can share state between each call, consider using `ScratchSpace` and the `extend_with` method.
39//! This can avoid excessive allocations that the `Extend` method would otherwise have (as it needs
40//! to allocate to insert many items at once).
41//!
42//! ## Basic usage
43//! ```rust
44//! use prefix_array::PrefixArray;
45//!
46//! // construct a new prefix array from an iterator
47//! let arr = PrefixArray::from_iter([("abcde", 123), ("absgh", 1234)]);
48//!
49//! // borrow a subslice of all data with the prefix 'ab'
50//! let mut subslice = arr.find_all_with_prefix("ab");
51//!
52//! assert_eq!(subslice.len(), 2);
53//!
54//! // we can refine the subslice
55//! subslice = subslice.find_all_with_prefix("abc");
56//!
57//! assert_eq!(subslice.len(), 1);
58//!
59//! // and find when something doesn't exist
60//! assert!(subslice.find_all_with_prefix("ba").is_empty());
61//! ```
62
63pub mod map;
64pub use map::{PrefixArray, SubSlice};
65
66pub mod set;
67pub use set::{PrefixArraySet, SetSubSlice};
68
69pub mod shared;