//! Produce and resolve tags. use crate::error::ResolveError; use crate::label::DefaultLabel; use crate::label::Label; use crate::parse::*; use crate::storage::Storage; use crate::tag::KeyValueSep; #[cfg(doc)] use crate::tag::KeyValueTag; #[cfg(doc)] use crate::tag::MultipartTag; use crate::tag::PathSep; use crate::tag::PlainTag; use crate::tag::Tag; use crate::{error::ParseError, tag::TagKind}; #[cfg(doc)] use std::sync::Mutex; use std::{convert::identity, hash::BuildHasher}; use string_interner::backend::Backend as InternerBackend; use string_interner::DefaultBackend; use string_interner::DefaultHashBuilder; use string_interner::DefaultSymbol; #[cfg(doc)] use string_interner::StringInterner; use string_interner::Symbol; use typed_builder::TypedBuilder; /// Constructs [`Tag`]s according to the configured parser and interner. /// /// A single [`TagManager`] is responsible for parsing and resolving tags that /// match the rules of a single configured parser, with storage handled by /// an underlying [`StringInterner`]. The [`StringInterner`] may be shared /// with other [`TagManager`]s. /// /// [`TagManager`] is designed to be generic over: /// /// - The parser used to produce tags. /// - The interner used to store tag data. /// /// The trait bounds on [`TagManager`] ensure that the parser and interner /// agree on the [`Symbol`] used as handles for the stored string data. /// This is required because the parser produces [`Tag`]s which store /// [`Symbol`]s so they can later be resolved into [`String`]s to recover /// the full originally-input tag data. /// /// The manner in which tag data is stored depends on the `T` parameter. /// [`PlainTag`] stores the full string data in the interner. [`KeyValueTag`] /// stores the key and value data separately, on the expectation that keys /// especially will be repeated, and thus a lot of space saving is achieved by /// deduplicating them through separate interning. [`MultipartTag`] stores /// each part separately, again on the expectation that individual parts will /// be frequently repeated across tags, resulting in space savings from interning. #[derive(TypedBuilder)] pub struct TagManager< L = DefaultLabel, S = DefaultSymbol, T = PlainTag, P = Plain, B = DefaultBackend, H = DefaultHashBuilder, > where L: Label, S: Symbol, T: Tag