use crate::accum_ftzr::{Ftzr, IterFtzr, LinearFixed};
#[cfg(feature = "serde1")]
use serde::{Deserialize, Serialize};
use std::marker::PhantomData;
#[derive(Hash, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Debug)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct ForEach<F, Meta>(F, PhantomData<Meta>);
#[derive(Hash, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Debug)]
pub struct ForEachIter<F, Sentence, Word, SentIter, FWordIter> {
ftzr: F,
sentence: SentIter,
current: Option<FWordIter>,
tags: PhantomData<(Sentence, Word)>,
}
impl<F, Sentence, Word, SentIter> Iterator
for ForEachIter<F, Sentence, Word, SentIter, <F as IterFtzr<Word>>::Iter>
where
SentIter: Iterator<Item = Word>,
F: IterFtzr<Word>,
{
type Item = F::TokenGroup;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(current) = self.current.as_mut() {
if let Some(token_group) = current.next() {
return Some(token_group);
}
}
{
let word = self.sentence.next()?;
self.current = Some(self.ftzr.iterate_features(word))
}
}
}
}
impl<F: LinearFixed, T> LinearFixed for ForEach<F, T> {
fn chunk_size(&self) -> usize {
self.0.chunk_size()
}
}
impl<F, Sentence, Word> IterFtzr<Sentence> for ForEach<F, (Sentence, Word)>
where
Sentence: IntoIterator<Item = Word>,
F: IterFtzr<Word> + Clone,
{
type TokenGroup = F::TokenGroup;
type Iter = ForEachIter<F, Sentence, Word, Sentence::IntoIter, F::Iter>;
fn iterate_features(&self, origin: Sentence) -> Self::Iter {
ForEachIter {
ftzr: self.0.clone(),
sentence: origin.into_iter(),
current: None,
tags: PhantomData,
}
}
}
impl<F, Sentence, Word> Ftzr<Sentence> for ForEach<F, (Sentence, Word)>
where
Sentence: IntoIterator<Item = Word>,
F: Ftzr<Word>,
{
type TokenGroup = F::TokenGroup;
fn push_tokens<Push>(&self, origin: Sentence, push: &mut Push)
where
Push: FnMut(Self::TokenGroup),
{
for word in origin.into_iter() {
self.0.push_tokens(word, push);
}
}
}
pub fn for_each<F, Sentence, Word>(f: F) -> ForEach<F, (Sentence, Word)> {
ForEach(f, PhantomData)
}