harper_core/patterns/
exact_phrase.rs

1use crate::{Document, Token, TokenKind};
2
3use super::{Pattern, SequencePattern, Word};
4
5pub struct ExactPhrase {
6    inner: SequencePattern,
7}
8
9impl ExactPhrase {
10    pub fn from_phrase(text: &str) -> Self {
11        let document = Document::new_markdown_default_curated(text);
12        Self::from_document(&document)
13    }
14
15    pub fn from_document(doc: &Document) -> Self {
16        let mut phrase = SequencePattern::default();
17
18        for token in doc.fat_tokens() {
19            match token.kind {
20                TokenKind::Word(_word_metadata) => {
21                    phrase = phrase.then(Word::from_chars(token.content.as_slice()));
22                }
23                TokenKind::Space(_) => {
24                    phrase = phrase.then_whitespace();
25                }
26                TokenKind::Punctuation(p) => {
27                    phrase = phrase.then(move |t: &Token, _source: &[char]| {
28                        t.kind.as_punctuation().cloned() == Some(p)
29                    })
30                }
31                TokenKind::ParagraphBreak => {
32                    phrase = phrase.then_whitespace();
33                }
34                TokenKind::Number(n) => {
35                    phrase = phrase
36                        .then(move |tok: &Token, _source: &[char]| tok.kind == TokenKind::Number(n))
37                }
38                _ => panic!("Fell out of expected document formats."),
39            }
40        }
41
42        Self { inner: phrase }
43    }
44}
45
46impl Pattern for ExactPhrase {
47    fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
48        self.inner.matches(tokens, source)
49    }
50}