use super::WordList as WordListCStr;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct WordList<'u, 'l: 'u>(&'u WordListCStr<'l>);
impl<'u, 'l: 'u> From<&'u WordListCStr<'l>> for WordList<'u, 'l> {
fn from(word_list: &'u WordListCStr<'l>) -> Self {
WordList(word_list)
}
}
impl<'u, 'l: 'u> std::ops::Index<usize> for WordList<'u, 'l> {
type Output = str;
fn index(&self, index: usize) -> &'u Self::Output {
match self.0[index].to_str() {
Ok(s) => s,
Err(e) => panic!("invalid utf-8 in word: {}", e),
}
}
}
impl<'u, 'l: 'u> WordList<'u, 'l> {
pub fn new(list: &'u WordListCStr<'l>) -> Self {
list.into()
}
pub fn new_eager(list: &'u WordListCStr<'l>) -> Result<Self, std::str::Utf8Error> {
list.into_iter()
.fold(Ok(list), |original, element| element.to_str().and(original))
.map(WordList)
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn get(&self, index: usize) -> Option<&<Self as std::ops::Index<usize>>::Output> {
if index < self.len() {
Some(&self[index])
} else {
None
}
}
pub unsafe fn get_unchecked(&self, index: usize) -> &<Self as std::ops::Index<usize>>::Output {
let element = self.0.get_unchecked(index);
let bytes = element.to_bytes();
std::str::from_utf8_unchecked(bytes)
}
}
pub struct Iter<'r, 'u: 'r, 'l: 'u> {
word_list: &'r WordList<'u, 'l>,
index: usize,
}
impl<'r, 'u: 'r, 'l: 'u> IntoIterator for &'r WordList<'u, 'l> {
type IntoIter = Iter<'r, 'u, 'l>;
type Item = <Self::IntoIter as Iterator>::Item;
fn into_iter(self) -> Self::IntoIter {
Iter {
word_list: self,
index: 0,
}
}
}
impl<'r, 'u: 'r, 'l: 'u> Iterator for Iter<'r, 'u, 'l> {
type Item = &'r <WordList<'u, 'l> as std::ops::Index<usize>>::Output;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.word_list.len() {
None
} else {
let result = &self.word_list[self.index];
self.index += 1;
Some(result)
}
}
}