#[cfg(feature = "mem_dbg")]
use alloc::{string::String, vec::Vec};
use crate::{
errors::builder::vocabulary::VocabularyBuilderError,
traits::{GrowableVocabulary, Vocabulary, VocabularyBuilder},
};
#[cfg_attr(feature = "mem_size", derive(mem_dbg::MemSize))]
#[cfg_attr(feature = "mem_size", mem_size(rec))]
#[cfg_attr(feature = "mem_dbg", derive(mem_dbg::MemDbg))]
#[derive(Clone, Debug)]
pub struct GenericVocabularyBuilder<Symbols, Vocabulary> {
symbols: Option<Symbols>,
expected_number_of_symbols: Option<usize>,
ignore_duplicates: bool,
_vocabulary: core::marker::PhantomData<Vocabulary>,
}
impl<Symbols, V> Default for GenericVocabularyBuilder<Symbols, V> {
#[inline]
fn default() -> Self {
Self {
symbols: None,
expected_number_of_symbols: None,
ignore_duplicates: false,
_vocabulary: core::marker::PhantomData,
}
}
}
impl<Symbols, V: GrowableVocabulary> VocabularyBuilder for GenericVocabularyBuilder<Symbols, V>
where
Symbols: IntoIterator<
Item = (<V as Vocabulary>::SourceSymbol, <V as Vocabulary>::DestinationSymbol),
>,
{
type Symbols = Symbols;
type Vocabulary = V;
#[inline]
fn expected_number_of_symbols(mut self, number_of_symbols: usize) -> Self {
self.expected_number_of_symbols = Some(number_of_symbols);
self
}
#[inline]
fn get_expected_number_of_symbols(&self) -> Option<usize> {
self.expected_number_of_symbols
}
#[inline]
fn ignore_duplicates(mut self) -> Self {
self.ignore_duplicates = true;
self
}
#[inline]
fn should_ignore_duplicates(&self) -> bool {
self.ignore_duplicates
}
#[inline]
fn symbols(mut self, symbols: Self::Symbols) -> Self {
self.symbols = Some(symbols);
self
}
}
impl<Symbols, V> GenericVocabularyBuilder<Symbols, V>
where
Self: VocabularyBuilder<Symbols = Symbols>,
Symbols: IntoIterator<
Item = (
<<Self as VocabularyBuilder>::Vocabulary as Vocabulary>::SourceSymbol,
<<Self as VocabularyBuilder>::Vocabulary as Vocabulary>::DestinationSymbol,
),
>,
{
#[inline]
pub fn build(
self,
) -> Result<
<Self as VocabularyBuilder>::Vocabulary,
VocabularyBuilderError<<Self as VocabularyBuilder>::Vocabulary>,
> {
let expected_number_of_symbols = self.get_expected_number_of_symbols();
let mut vocabulary = if let Some(number_of_symbols) = expected_number_of_symbols {
<Self as VocabularyBuilder>::Vocabulary::with_capacity(number_of_symbols)
} else {
<Self as VocabularyBuilder>::Vocabulary::new()
};
let should_ignore_duplicates = self.should_ignore_duplicates();
self.symbols
.ok_or(VocabularyBuilderError::MissingAttribute("symbols"))?
.into_iter()
.try_for_each(|(source, destination)| {
if let Err(err) = vocabulary.add(source, destination) {
match err {
crate::errors::builder::vocabulary::VocabularyBuilderError::RepeatedSourceSymbol(
_,
) | crate::errors::builder::vocabulary::VocabularyBuilderError::RepeatedDestinationSymbol(
_,
) => {
if should_ignore_duplicates {
Ok(())
} else {
Err(err)
}
}
other => Err(other)
}
} else {
Ok(())
}
})?;
if let Some(expected_number_of_symbols) = expected_number_of_symbols
&& vocabulary.len() != expected_number_of_symbols
{
return Err(
crate::errors::builder::vocabulary::VocabularyBuilderError::NumberOfSymbols {
expected: expected_number_of_symbols,
actual: vocabulary.len(),
},
);
}
Ok(vocabulary)
}
}