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
//! A type-agnostic interner
//!
//! Can be used to deduplicate various structures for fast equality comparisons.
//! The design favours flexibility over efficiency, ideally you can throw
//! any type into [i] and it'll just work.
//!
//! ```
//! use std::env;
//! use std::path::PathBuf;
//!
//! use intern_all::{i, Tok};
//!
//! // Intern a value
//! let a: Tok<String> = i("foo");
//! // Intern a path
//! let b: Tok<PathBuf> = i(&env::current_dir().unwrap());
//! ```
//!
//! Some convenience methods are also provided to make working with lists
//! easier.
//!
//! ```
//! use intern_all::{i, ibv, iv, Tok};
//!
//! // Intern a list as a slice of tokens
//! let v1: Tok<Vec<Tok<String>>> = i(&[i("bar"), i("quz"), i("quux")][..]);
//! // Intern a list of internable values
//! let v2: Tok<Vec<Tok<String>>> = iv(["bar".to_string(), "quz".to_string(), "quux".to_string()]);
//! // Intern a list of the borrowed form of internable values
//! let v3: Tok<Vec<Tok<String>>> = ibv(["bar", "quz", "quux"]);
//! assert!(v1 == v2 && v2 == v3)
//! ```
//!
//! The interner uses weak references but the unreferenced values still take up
//! space in the token table. To avoid a memory leak, you can periodically
//! sremove entries referring to unreferenced values from the interner with
//! [sweep] or [sweep_t].
//!
//! ```
//! use intern_all::{sweep, sweep_t};
//!
//! // use this for general housekeeping
//! sweep();
//! // use this if a lot of temporary values of a particular interned type
//! // had been dropped recently
//! sweep_t::<String>();
//! ```
//!
//! The functions exposed by this crate have short and not very descriptive
//! names, which may seem like a red flag. In a typical use case, these
//! functions would appear everywhere in the codebase, so this is not a concern.
mod global;
#[warn(unsafe_code)]
mod interner;
mod token;
mod typed_interner;
pub use global::{ev, i, ibv, iv, sweep, sweep_t};
pub use token::{Internable, Tok};
pub mod instance {
//! The interner uses weak references and can be cleared with [sweep], but if
//! you want to avoid using a global singleton, you can construct an instance
//! too. Comparing tokens from different interners causes a panic.
//!
//! ```
//! use intern_all::instance::Interner;
//!
//! // But you can also create an instance which has methods corresponding to
//! // all the above functions:
//! let int = Interner::new();
//! let k = int.i("foobar");
//! ```
pub use super::interner::Interner;
pub use super::typed_interner::TypedInterner;
}