Skip to main content

harper_core/patterns/
modal_verb.rs

1use std::sync::LazyLock;
2
3use super::{Pattern, WordSet};
4
5static MODALS: [&str; 14] = [
6    "can", "can't", "could", "may", "might", "must", "shall", "shan't", "should", "will", "won't",
7    "would", "ought", "dare",
8];
9
10pub struct ModalVerb {
11    inner: &'static WordSet,
12}
13
14impl Default for ModalVerb {
15    fn default() -> Self {
16        Self::without_common_errors()
17    }
18}
19
20impl ModalVerb {
21    pub fn without_common_errors() -> Self {
22        static CACHED_WITHOUT_COMMON_ERRORS: LazyLock<WordSet> = LazyLock::new(|| {
23            let mut words = WordSet::new(&MODALS);
24            MODALS.iter().for_each(|word| {
25                words.add(&format!("{word}n't"));
26            });
27            words.add("cannot");
28            words
29        });
30
31        Self {
32            inner: &CACHED_WITHOUT_COMMON_ERRORS,
33        }
34    }
35
36    pub fn with_common_errors() -> Self {
37        static CACHED_WITH_COMMON_ERRORS: LazyLock<WordSet> = LazyLock::new(|| {
38            let mut words = WordSet::new(&MODALS);
39            MODALS.iter().for_each(|word| {
40                words.add(&format!("{word}n't"));
41                words.add(&format!("{word}nt"));
42            });
43            words.add("cannot");
44            words
45        });
46
47        Self {
48            inner: &CACHED_WITH_COMMON_ERRORS,
49        }
50    }
51}
52
53impl Pattern for ModalVerb {
54    fn matches(&self, tokens: &[crate::Token], source: &[char]) -> Option<usize> {
55        self.inner.matches(tokens, source)
56    }
57}