harper_core/expr/
anchor_end.rs

1use crate::Token;
2
3use super::Step;
4
5/// A [`Step`] which will match only if the cursor is over the last non-whitespace character in stream.
6/// It will return that token.
7///
8/// For example, if you built `SequenceExpr::default().t_aco("word").then(AnchorEnd)` and ran it on `This is a word`, the resulting `Span` would only cover the final word token.
9pub struct AnchorEnd;
10
11impl Step for AnchorEnd {
12    fn step(&self, tokens: &[Token], cursor: usize, _source: &[char]) -> Option<isize> {
13        if tokens
14            .iter()
15            .enumerate()
16            .rev()
17            .filter(|(_, t)| !t.kind.is_whitespace())
18            .map(|(i, _)| i)
19            .next()
20            == Some(cursor)
21        {
22            Some(0)
23        } else {
24            None
25        }
26    }
27}
28
29#[cfg(test)]
30mod tests {
31    use crate::expr::ExprExt;
32    use crate::{Document, Span};
33
34    use super::AnchorEnd;
35
36    #[test]
37    fn matches_period() {
38        let document = Document::new_markdown_default_curated("This is a test.");
39        let matches: Vec<_> = AnchorEnd.iter_matches_in_doc(&document).collect();
40
41        assert_eq!(matches, vec![Span::new(7, 7)])
42    }
43
44    #[test]
45    fn does_not_match_empty() {
46        let document = Document::new_markdown_default_curated("");
47        let matches: Vec<_> = AnchorEnd.iter_matches_in_doc(&document).collect();
48
49        assert_eq!(matches, vec![])
50    }
51}