//! Different kinds of [`Tag`]s that can be parsed. use crate::error::ResolveError; use crate::label::DefaultLabel; use crate::label::Label; #[cfg(doc)] use crate::storage::Storage; use crate::storage::StorageLock; #[cfg(doc)] use crate::TagManager; #[cfg(feature = "either")] use either::Either; use itertools::intersperse_with; use std::fmt::Display; use std::fmt::Formatter; use std::fmt::Result as FmtResult; use std::hash::BuildHasher; use std::marker::PhantomData; use string_interner::backend::Backend as InternerBackend; use string_interner::DefaultSymbol; #[cfg(doc)] use string_interner::StringInterner; use string_interner::Symbol; /// A trait defining a [`Tag`] which contains interned data. /// /// The _only_ defining operation of a [`Tag`] is that it can be /// converted back into a [`String`] using the [`Storage`] that /// created it and the correct separator configured by the [`TagManager`] /// that built it. /// /// [`Tag`]s have an underlying [`Symbol`] used to define their storage. /// Internally, [`Tag`]s are just a set of [`Symbol`]s used to make /// storage and identity comparison cheap while enabling reconstruction /// of the original [`String`]. pub trait Tag { /// The label of the [`TagManager`] used to produce the [`Tag`]. type Label: Label; /// The [`Symbol`] used by the [`Storage`] as a handle to the stored string data. type Symbol: Symbol; /// Get the [`TagKind`] of the current tag. fn kind(&self) -> TagKind; /// Try to resolve a [`Tag`] back into a [`String`]. fn resolve( &self, storage: &StorageLock<'_, Self::Label, B, H>, key_value_separator: KeyValueSep, path_separator: PathSep, ) -> Result where B: InternerBackend, H: BuildHasher; } #[cfg(feature = "either")] // Auto-impl for `Either` wrapping two `Tag`s. impl Tag for Either where L: Label, S: Symbol, T1: Tag