use crate::{annotate::AnnotatedTextFragment, dictionary::TextEntry};
pub trait Select<'a> {
fn select(&'_ self, fragment: &'a AnnotatedTextFragment<'a>) -> Option<&'a TextEntry>;
}
pub mod heuristic {
use crate::{annotate::AnnotatedTextFragment, dictionary::TextEntry};
use super::Select;
pub struct All;
impl<'a> Select<'a> for All {
fn select(&self, fragment: &AnnotatedTextFragment<'a>) -> Option<&'a TextEntry> {
fragment.annotations.get(0).copied()
}
}
pub struct UncommonOnly;
impl<'a> Select<'a> for UncommonOnly {
fn select(&self, fragment: &AnnotatedTextFragment<'a>) -> Option<&'a TextEntry> {
match fragment.annotations.get(0) {
Some(entry) if !entry.text_is_common && !entry.reading_is_common => Some(entry),
_ => None,
}
}
}
}
pub mod filter {
use std::{
collections::HashSet,
sync::{Arc, RwLock},
};
use crate::{annotate::AnnotatedTextFragment, dictionary::TextEntry};
use super::Select;
#[derive(Clone, Debug)]
pub struct FirstOccurrence<'a, S: Select<'a>> {
seen: Arc<RwLock<HashSet<&'a str>>>,
selector: S,
}
impl<'a, S: Select<'a>> FirstOccurrence<'a, S> {
pub fn new(selector: S) -> Self {
Self {
seen: Arc::default(),
selector,
}
}
}
impl<'a, S: Select<'a>> Select<'a> for FirstOccurrence<'a, S> {
fn select(&'_ self, fragment: &'a AnnotatedTextFragment<'a>) -> Option<&'a TextEntry> {
let mut set = self.seen.write().unwrap();
if (*set).insert(&fragment.text) {
self.selector.select(fragment)
} else {
None
}
}
}
}