use std::cell::RefCell;
use super::SingleTokenPattern;
use crate::{CharString, CharStringExt, Token};
use crate::edit_distance::edit_distance_min_alloc;
pub struct WithinEditDistance {
word: CharString,
max_edit_dist: u8,
}
impl WithinEditDistance {
pub fn new(word: CharString, max_edit_dist: u8) -> Self {
Self {
word,
max_edit_dist,
}
}
pub fn from_str(word: &str, edit_dist: u8) -> Self {
let chars = word.chars().collect();
Self::new(chars, edit_dist)
}
}
thread_local! {
static BUFFERS: RefCell<(Vec<u8>, Vec<u8>)> = const { RefCell::new((Vec::new(), Vec::new())) };
}
impl SingleTokenPattern for WithinEditDistance {
fn matches_token(&self, token: &Token, source: &[char]) -> bool {
if !token.kind.is_word() {
return false;
}
let content = token.get_ch(source);
BUFFERS.with_borrow_mut(|(buffer_a, buffer_b)| {
let distance = edit_distance_min_alloc(
&content.to_lower(),
&self.word.to_lower(),
buffer_a,
buffer_b,
);
distance <= self.max_edit_dist
})
}
}