diff --git a/.changes/fix-router.md b/.changes/fix-router.md new file mode 100644 index 0000000..8d2c26f --- /dev/null +++ b/.changes/fix-router.md @@ -0,0 +1,5 @@ +--- +"aionbot-core": patch:fix +--- + +Fix command router matches for different prefixes. diff --git a/Cargo.lock b/Cargo.lock index 6f0edf7..520f5fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,7 +28,7 @@ dependencies = [ [[package]] name = "aionbot" -version = "0.1.0" +version = "0.1.1" dependencies = [ "aionbot-core", "aionbot-macros", @@ -41,7 +41,7 @@ dependencies = [ [[package]] name = "aionbot-adapter-onebot" -version = "0.1.0" +version = "0.1.1" dependencies = [ "aionbot-core", "anyhow", @@ -55,7 +55,7 @@ dependencies = [ [[package]] name = "aionbot-core" -version = "0.1.0" +version = "0.1.2" dependencies = [ "anyhow", "futures", diff --git a/crates/aionbot-core/src/event.rs b/crates/aionbot-core/src/event.rs index b0ed0c8..6dd9b89 100644 --- a/crates/aionbot-core/src/event.rs +++ b/crates/aionbot-core/src/event.rs @@ -53,3 +53,18 @@ pub trait Event: Any + Send + Sync { } fn as_any(&self) -> &dyn Any; } + +impl Event for String { + fn event_type(&self) -> &str { + "string_event" + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn content(&self) -> Box { + let str: &str = self.clone().leak(); + Box::new(str) + } +} diff --git a/crates/aionbot-core/src/router.rs b/crates/aionbot-core/src/router.rs index f4e17cd..b1ed136 100644 --- a/crates/aionbot-core/src/router.rs +++ b/crates/aionbot-core/src/router.rs @@ -153,13 +153,35 @@ pub struct CommandRouter { pub command: String, } +impl Default for CommandRouter { + fn default() -> Self { + Self { + prefixes: vec!["/".to_string()], + command: "help".to_string(), + } + } +} + +impl CommandRouter { + pub fn new(prefixes: Vec, command: String) -> Self { + Self { prefixes, command } + } + + pub fn command(command: impl ToString) -> Self { + Self { + command: command.to_string(), + ..Default::default() + } + } +} + impl Router for CommandRouter { fn matches(&self, event: &dyn Event) -> bool { if let Ok(val) = event.content().downcast::<&str>() { for prefix in &self.prefixes { if val.starts_with(prefix) { let command = val.strip_prefix(prefix).unwrap(); - if command == self.command { + if command.starts_with(self.command.as_str()) { return true; } } @@ -170,3 +192,30 @@ impl Router for CommandRouter { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_command_router() { + let router = CommandRouter::default(); + assert!(!router.matches(&"help".to_string())); + assert!(router.matches(&"/help".to_string())); + assert!(router.matches(&"/help@bot".to_string())); + assert!(!router.matches(&"/not help".to_string())); + + let router = CommandRouter::command("cmd"); + assert!(!router.matches(&"help".to_string())); + assert!(router.matches(&"/cmd".to_string())); + assert!(router.matches(&"/cmd@bot".to_string())); + assert!(!router.matches(&"/not cmd".to_string())); + + let router = CommandRouter::new(vec!["!".to_string()], "cmd".to_string()); + assert!(!router.matches(&"help".to_string())); + assert!(router.matches(&"!cmd".to_string())); + assert!(router.matches(&"!cmd@bot".to_string())); + assert!(!router.matches(&"!not cmd".to_string())); + assert!(!router.matches(&"/cmd arg1 arg2".to_string())) + } +}