use crate::accum_ftzr::{Ftzr, IterFtzr, LinearFixed};
use crate::as_tokens::AsTokens;
#[cfg(feature = "serde1")]
use serde::{Deserialize, Serialize};
#[derive(Hash, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Debug)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct SliceGram {
n: usize,
}
pub fn n_slice(n: usize) -> SliceGram {
SliceGram { n }
}
pub fn bislice() -> SliceGram {
SliceGram { n: 2 }
}
pub fn trislice() -> SliceGram {
SliceGram { n: 3 }
}
#[derive(Hash, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Debug)]
pub struct SliceGramIter<Origin> {
n: usize,
idx: usize,
data: Origin,
}
impl<'a, T: 'a> Iterator for SliceGramIter<&'a [T]> {
type Item = &'a [T];
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let jdx = self.idx + self.n;
if jdx <= self.data.len() {
let ret = Some(&self.data[self.idx..jdx]);
self.idx += 1;
ret
} else {
None
}
}
}
impl LinearFixed for SliceGram {
fn chunk_size(&self) -> usize {
self.n
}
}
impl<'a, D, T: 'a> IterFtzr<&'a D> for SliceGram
where
D: AsTokens<Token = T> + ?Sized,
{
type TokenGroup = &'a [T];
type Iter = SliceGramIter<&'a [T]>;
fn iterate_features(&self, origin: &'a D) -> Self::Iter {
SliceGramIter {
n: self.n,
idx: 0,
data: origin.as_tokens(),
}
}
}
impl<Origin> Ftzr<Origin> for SliceGram
where
Self: IterFtzr<Origin>,
{
type TokenGroup = <Self as IterFtzr<Origin>>::TokenGroup;
fn push_tokens<Push>(&self, origin: Origin, push: &mut Push)
where
Push: FnMut(Self::TokenGroup),
{
for t in self.iterate_features(origin) {
push(t)
}
}
}