#[cfg(feature = "alloc")]
use alloc::{boxed::Box, rc::Rc};
use core::fmt::Debug;
use crate::{errors::builder::vocabulary::VocabularyBuilderError, traits::Symbol};
pub trait Vocabulary: Debug {
type SourceSymbol: Symbol;
type DestinationSymbol: Symbol;
type Sources<'a>: Iterator<Item = Self::SourceSymbol>
where
Self: 'a;
type Destinations<'a>: Iterator<Item = Self::DestinationSymbol>
where
Self: 'a;
fn convert(&self, source: &Self::SourceSymbol) -> Option<Self::DestinationSymbol>;
#[inline]
fn is_empty(&self) -> bool {
self.len() == 0
}
fn len(&self) -> usize;
fn sources(&self) -> Self::Sources<'_>;
fn destinations(&self) -> Self::Destinations<'_>;
}
impl<V: Vocabulary + ?Sized> Vocabulary for &V {
type SourceSymbol = V::SourceSymbol;
type DestinationSymbol = V::DestinationSymbol;
type Sources<'a>
= V::Sources<'a>
where
Self: 'a;
type Destinations<'a>
= V::Destinations<'a>
where
Self: 'a;
#[inline]
fn convert(&self, source: &Self::SourceSymbol) -> Option<Self::DestinationSymbol> {
(*self).convert(source)
}
#[inline]
fn len(&self) -> usize {
(*self).len()
}
#[inline]
fn sources(&self) -> Self::Sources<'_> {
(*self).sources()
}
#[inline]
fn destinations(&self) -> Self::Destinations<'_> {
(*self).destinations()
}
}
#[cfg(feature = "alloc")]
impl<V: Vocabulary + ?Sized> Vocabulary for Box<V> {
type SourceSymbol = V::SourceSymbol;
type DestinationSymbol = V::DestinationSymbol;
type Sources<'a>
= V::Sources<'a>
where
Self: 'a;
type Destinations<'a>
= V::Destinations<'a>
where
Self: 'a;
#[inline]
fn convert(&self, source: &Self::SourceSymbol) -> Option<Self::DestinationSymbol> {
(**self).convert(source)
}
#[inline]
fn len(&self) -> usize {
(**self).len()
}
#[inline]
fn sources(&self) -> Self::Sources<'_> {
(**self).sources()
}
#[inline]
fn destinations(&self) -> Self::Destinations<'_> {
(**self).destinations()
}
}
#[cfg(feature = "alloc")]
impl<V: Vocabulary + ?Sized> Vocabulary for Rc<V> {
type SourceSymbol = V::SourceSymbol;
type DestinationSymbol = V::DestinationSymbol;
type Sources<'a>
= V::Sources<'a>
where
Self: 'a;
type Destinations<'a>
= V::Destinations<'a>
where
Self: 'a;
#[inline]
fn convert(&self, source: &Self::SourceSymbol) -> Option<Self::DestinationSymbol> {
(**self).convert(source)
}
#[inline]
fn len(&self) -> usize {
(**self).len()
}
#[inline]
fn sources(&self) -> Self::Sources<'_> {
(**self).sources()
}
#[inline]
fn destinations(&self) -> Self::Destinations<'_> {
(**self).destinations()
}
}
pub trait VocabularyRef: Vocabulary {
type DestinationRefs<'a>: Iterator<Item = &'a Self::DestinationSymbol>
where
Self: 'a;
fn convert_ref(&self, source: &Self::SourceSymbol) -> Option<&Self::DestinationSymbol>;
fn destination_refs(&self) -> Self::DestinationRefs<'_>;
}
impl<V: VocabularyRef + ?Sized> VocabularyRef for &V {
type DestinationRefs<'a>
= V::DestinationRefs<'a>
where
Self: 'a;
#[inline]
fn convert_ref(&self, source: &Self::SourceSymbol) -> Option<&Self::DestinationSymbol> {
(*self).convert_ref(source)
}
#[inline]
fn destination_refs(&self) -> Self::DestinationRefs<'_> {
(*self).destination_refs()
}
}
pub trait BidirectionalVocabulary: Vocabulary {
fn invert(&self, destination: &Self::DestinationSymbol) -> Option<Self::SourceSymbol>;
}
impl<V: BidirectionalVocabulary + ?Sized> BidirectionalVocabulary for &V {
#[inline]
fn invert(&self, destination: &Self::DestinationSymbol) -> Option<Self::SourceSymbol> {
(*self).invert(destination)
}
}
#[cfg(feature = "alloc")]
impl<V: BidirectionalVocabulary + ?Sized> BidirectionalVocabulary for Box<V> {
#[inline]
fn invert(&self, destination: &Self::DestinationSymbol) -> Option<Self::SourceSymbol> {
(**self).invert(destination)
}
}
#[cfg(feature = "alloc")]
impl<V: BidirectionalVocabulary + ?Sized> BidirectionalVocabulary for Rc<V> {
#[inline]
fn invert(&self, destination: &Self::DestinationSymbol) -> Option<Self::SourceSymbol> {
(**self).invert(destination)
}
}
pub trait BidirectionalVocabularyRef: BidirectionalVocabulary + VocabularyRef {
type SourceRefs<'a>: Iterator<Item = &'a Self::SourceSymbol>
where
Self: 'a;
fn invert_ref(&self, destination: &Self::DestinationSymbol) -> Option<&Self::SourceSymbol>;
fn source_refs(&self) -> Self::SourceRefs<'_>;
}
impl<V: BidirectionalVocabularyRef + ?Sized> BidirectionalVocabularyRef for &V {
type SourceRefs<'a>
= V::SourceRefs<'a>
where
Self: 'a;
#[inline]
fn invert_ref(&self, destination: &Self::DestinationSymbol) -> Option<&Self::SourceSymbol> {
(*self).invert_ref(destination)
}
#[inline]
fn source_refs(&self) -> Self::SourceRefs<'_> {
(*self).source_refs()
}
}
pub trait GrowableVocabulary: Vocabulary + Default {
fn new() -> Self;
fn with_capacity(capacity: usize) -> Self;
fn add(
&mut self,
source: Self::SourceSymbol,
destination: Self::DestinationSymbol,
) -> Result<(), VocabularyBuilderError<Self>>;
}