initiative_core/command/token/
any_word.rs

1use crate::command::prelude::*;
2use crate::utils::quoted_words;
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::AnyWord));
14
15    Box::pin(stream! {
16        let mut iter = quoted_words(input);
17        if let Some(word) = iter.next() {
18            let token_match = TokenMatch::new(token, word.as_str());
19
20            if word.is_at_end() {
21                yield FuzzyMatch::Exact(token_match);
22            } else {
23                yield FuzzyMatch::Overflow(token_match, word.after());
24            }
25        }
26    })
27}
28
29#[cfg(test)]
30mod test {
31    use super::*;
32
33    use crate::test_utils as test;
34
35    #[derive(Hash)]
36    enum Marker {
37        Token,
38    }
39
40    #[tokio::test]
41    async fn match_input_test_exact() {
42        let token = any_word();
43
44        test::assert_eq_unordered!(
45            [FuzzyMatch::Exact(TokenMatch::new(&token, "Jesta"))],
46            token
47                .match_input("Jesta", &test::app_meta())
48                .collect::<Vec<_>>()
49                .await,
50        );
51    }
52
53    #[tokio::test]
54    async fn match_input_test_overflow() {
55        let token = any_word_m(Marker::Token);
56
57        test::assert_eq_unordered!(
58            [FuzzyMatch::Overflow(
59                TokenMatch::new(&token, "Nott"),
60                " \"The Brave\" ".into()
61            )],
62            token
63                .match_input(" Nott \"The Brave\" ", &test::app_meta())
64                .collect::<Vec<_>>()
65                .await,
66        );
67    }
68}