initiative_core/command/token/
any_word.rs1use 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}