Crate symtern [−] [src]
Fast general-purpose interners for every use case
Symtern provides a high-performance interner implementation applicable to most use cases, and a small set of adaptors that add additional functionality on top of this base implementation.
Trait-guided implementation
Symtern's types are implemented around a core set of traits that define the ways you can interact with an interner; these traits are carefully designed to allow the adaptor
Interners and adaptors
The base interner, Pool
, is generic over the type of interned values,
and can be configured to use any of Rust's numeric primitives for symbol
IDs. It is the recommended interner for most purposes.
// Import Symtern's traits, which allow us to use each interner the same way // regardless of the underlying implementation. use symtern::prelude::*; // Create a new pool that accepts `&str` arguments to `intern`, and uses // `u8` as the backing representation for its symbol type. let mut pool = symtern::Pool::<str,u8>::new(); if let (Ok(hello), Ok(world)) = (pool.intern("Hello"), pool.intern("World")) { assert!(hello != world); assert_eq!(hello, hello); assert_eq!(Ok(hello), pool.intern("Hello")); assert_eq!(Ok("Hello"), pool.resolve(hello)); assert_eq!(world, world); assert_eq!(Ok(world), pool.intern("World")); assert_eq!(Ok("World"), pool.resolve(world)); }
Adaptors
For an overview of the available adaptors, see the [adaptors
module].
More examples
Symbol types are Copy
: they can be passed by
value without resulting in a move.
use symtern::prelude::*; use symtern::Pool; /// Take ownership of a value, consuming it. fn consume<T>(_: T) {} fn main() { let mut pool = Pool::<str, u32>::new(); let sym = pool.intern("xyz").unwrap(); consume(sym); println!("The symbol is still valid: {:?}", pool.resolve(sym)); }
Caveat Emptor
Because of the way symbol types in this crate are represented, a symbol
obtained by calling intern
on one Pool
instance can easily be identical
to a symbol obtained from a different instance of the same Pool
type
— and will resolve without error (albeit incorrectly) on that
other pool!
Present-day Rust affords us no easy way to fix this without incurring additional runtime costs; see the discussion here for more information.
When the crate is compiled in debug mode, an additional field is added to all symbol instances to allow run-time detection of attempts to resolve a symbol on the wrong resolver, and any such attempt will trigger a panic.
Modules
adaptors | |
prelude |
Items intended for glob-import. |
traits |
Traits that define the interface for all string-interning implementations. |
Structs
Error |
Error type used by this crate. |
Pool |
Simple hash-based interner generic over both the type of interned values and the type used to represent symbol IDs. |
Sym |
Symbol type used by |
Enums
ErrorKind |
Kinds of errors representable by the Error type. |
Type Definitions
Result |
Result type used by fallible operations in symtern. |