use core::{fmt, slice};
use crate::generated::{
LEXICON, LEXICON_OFFSETS, LEXICON_ORDERED_LENGTHS, LEXICON_SHORT_LENGTHS, PHRASEBOOK,
PHRASEBOOK_SHORT,
};
#[derive(Clone)]
pub struct IterStr {
phrasebook: slice::Iter<'static, u8>,
last_was_word: bool,
}
impl IterStr {
pub fn new(start_index: usize) -> IterStr {
IterStr {
phrasebook: PHRASEBOOK[start_index..].iter(),
last_was_word: false,
}
}
}
static HYPHEN: u8 = 127;
impl Iterator for IterStr {
type Item = &'static str;
fn next(&mut self) -> Option<&'static str> {
let mut tmp = self.phrasebook.clone();
tmp.next().map(|&raw_b| {
let (is_end, b) = (raw_b & 0b1000_0000 != 0, raw_b & 0b0111_1111);
let ret = if b == HYPHEN {
self.last_was_word = false;
"-"
} else if self.last_was_word {
self.last_was_word = false;
return " ";
} else {
self.last_was_word = true;
let idx;
let length = if b < PHRASEBOOK_SHORT {
idx = b as usize;
LEXICON_SHORT_LENGTHS[idx] as usize
} else {
idx = (b - PHRASEBOOK_SHORT) as usize * 256 + (*tmp.next().unwrap()) as usize;
match LEXICON_ORDERED_LENGTHS.iter().find(|&&(end, _)| idx < end) {
Some(&(_, len)) => len as usize,
None => unreachable!(),
}
};
let offset = LEXICON_OFFSETS[idx] as usize;
&LEXICON[offset..offset + length]
};
self.phrasebook = if is_end { ([]).iter() } else { tmp };
ret
})
}
}
impl fmt::Debug for IterStr {
fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
let printed = self.clone();
for s in printed {
write!(fmtr, "{}", s)?
}
Ok(())
}
}