initiative_core/command/token/
any_phrase.rs

1use crate::command::prelude::*;
2use crate::utils::quoted_phrases;
3
4use std::pin::Pin;
5
6use async_stream::stream;
7use futures::prelude::*;
8
9pub fn match_input<'a>(
10    token: &'a Token,
11    input: &'a str,
12) -> Pin<Box<dyn Stream<Item = FuzzyMatch<'a>> + 'a>> {
13    assert!(matches!(token.token_type, TokenType::AnyPhrase));
14
15    Box::pin(stream! {
16        let mut phrases = quoted_phrases(input).peekable();
17
18        while let Some(phrase) = phrases.next() {
19            let token_match = TokenMatch::new(token, phrase.as_str());
20
21            if phrases.peek().is_none() {
22                yield FuzzyMatch::Exact(token_match);
23            } else {
24                yield FuzzyMatch::Overflow(token_match, phrase.after());
25            }
26        }
27    })
28}
29
30#[cfg(test)]
31mod test {
32    use super::*;
33
34    use crate::test_utils as test;
35
36    #[derive(Hash)]
37    enum Marker {
38        Token,
39    }
40
41    #[tokio::test]
42    async fn match_input_test_empty() {
43        test::assert_empty!(
44            any_phrase()
45                .match_input("  ", &test::app_meta())
46                .collect::<Vec<_>>()
47                .await,
48        );
49    }
50
51    #[tokio::test]
52    async fn match_input_test_simple() {
53        let token = any_phrase();
54
55        test::assert_eq_unordered!(
56            [
57                FuzzyMatch::Overflow(TokenMatch::new(&token, "badger"), " badger badger".into()),
58                FuzzyMatch::Overflow(TokenMatch::new(&token, "badger badger"), " badger".into()),
59                FuzzyMatch::Exact(TokenMatch::new(&token, "badger badger badger")),
60            ],
61            token
62                .match_input("badger badger badger", &test::app_meta())
63                .collect::<Vec<_>>()
64                .await,
65        );
66    }
67
68    #[tokio::test]
69    async fn match_input_test_quoted() {
70        let token = any_phrase_m(Marker::Token);
71
72        test::assert_eq_unordered!(
73            [
74                FuzzyMatch::Overflow(TokenMatch::new(&token, "Nott"), " \"The Brave\" ".into()),
75                FuzzyMatch::Exact(TokenMatch::new(&token, "Nott \"The Brave\"")),
76            ],
77            token
78                .match_input(" Nott \"The Brave\" ", &test::app_meta())
79                .collect::<Vec<_>>()
80                .await,
81        );
82    }
83}