#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(u16)]
pub enum StopwordList {
None = 0,
LuceneEnglish = 1,
}
static LUCENE_ENGLISH: [&str; 33] = [
"a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it",
"no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these",
"they", "this", "to", "was", "will", "with",
];
impl StopwordList {
#[must_use]
pub const fn id(self) -> u16 {
self as u16
}
#[must_use]
pub const fn terms(self) -> &'static [&'static str] {
match self {
Self::None => &[],
Self::LuceneEnglish => &LUCENE_ENGLISH,
}
}
#[must_use]
pub fn contains(self, term: &str) -> bool {
self.terms().binary_search(&term).is_ok()
}
}
#[cfg(test)]
#[allow(clippy::expect_used, clippy::indexing_slicing, clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn the_lucene_list_is_sorted_and_complete() {
assert_eq!(LUCENE_ENGLISH.len(), 33);
assert!(
LUCENE_ENGLISH
.windows(2)
.all(|pair| match (pair.first(), pair.get(1)) {
(Some(left), Some(right)) => left < right,
_ => true,
}),
"the stopword list must be sorted for binary search"
);
}
#[test]
fn membership_matches_the_shipped_list() {
assert!(StopwordList::LuceneEnglish.contains("the"));
assert!(StopwordList::LuceneEnglish.contains("with"));
assert!(!StopwordList::LuceneEnglish.contains("engine"));
assert!(!StopwordList::None.contains("the"));
}
}