Skip to main content

aionbot_core/router/
command.rs

1use crate::event::Event;
2
3use super::Router;
4
5pub struct CommandRouter {
6    pub prefixes: Vec<String>,
7    pub command: Vec<String>,
8}
9
10impl Default for CommandRouter {
11    fn default() -> Self {
12        Self {
13            prefixes: vec!["/".into()],
14            command: ["help".into()].to_vec(),
15        }
16    }
17}
18
19impl CommandRouter {
20    pub fn new<S: Into<String>, C: IntoIterator<Item = S>>(
21        prefixes: Vec<String>,
22        command: C,
23    ) -> Self {
24        Self {
25            prefixes,
26            command: command.into_iter().map(Into::into).collect(),
27        }
28    }
29
30    pub fn command<S: Into<String>, C: IntoIterator<Item = S>>(command: C) -> Self {
31        Self {
32            command: command.into_iter().map(Into::into).collect(),
33            ..Default::default()
34        }
35    }
36}
37
38impl Router for CommandRouter {
39    fn matches(&self, event: &dyn Event) -> bool {
40        if let Ok(val) = event.content().downcast::<&str>() {
41            for prefix in &self.prefixes {
42                if val.starts_with(prefix) {
43                    let command = val.strip_prefix(prefix).unwrap();
44                    if self.command.iter().any(|c| command.starts_with(c)) {
45                        return true;
46                    }
47                }
48            }
49            false
50        } else {
51            false
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn test_command_router() {
62        let router = CommandRouter::default();
63        assert!(!router.matches(&"help".to_string()));
64        assert!(router.matches(&"/help".to_string()));
65        assert!(router.matches(&"/help@bot".to_string()));
66        assert!(!router.matches(&"/not help".to_string()));
67
68        let router = CommandRouter::command(["cmd", "command"]);
69        assert!(!router.matches(&"help".to_string()));
70        assert!(router.matches(&"/cmd".to_string()));
71        assert!(router.matches(&"/cmd@bot".to_string()));
72        assert!(!router.matches(&"/not cmd".to_string()));
73        assert!(router.matches(&"/command".to_string()));
74
75        let router = CommandRouter::new(vec!["!".to_string()], ["cmd"]);
76        assert!(!router.matches(&"help".to_string()));
77        assert!(router.matches(&"!cmd".to_string()));
78        assert!(router.matches(&"!cmd@bot".to_string()));
79        assert!(!router.matches(&"!not cmd".to_string()));
80        assert!(!router.matches(&"/cmd arg1 arg2".to_string()))
81    }
82}