Skip to content

Commit

Permalink
feat(router): optimize router (#30)
Browse files Browse the repository at this point in the history
* feat(router): optimize router

* feat(router): fix clippy warnings
  • Loading branch information
fu050409 authored Oct 28, 2024
1 parent 6905cdf commit 13c37fc
Show file tree
Hide file tree
Showing 10 changed files with 298 additions and 224 deletions.
5 changes: 5 additions & 0 deletions .changes/as-ref-router.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"aionbot-core": patch:feat
---

Optimize router implementation for `AsRef<str>`.
5 changes: 5 additions & 0 deletions .changes/command-alias.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"aionbot-core": patch:feat
---

Support alias command for `CommandRouter`.
5 changes: 5 additions & 0 deletions .changes/error-router.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"aionbot-core": patch:feat
---

Support router to match error event.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 30 additions & 1 deletion crates/aionbot-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,35 @@ pub mod handler;
pub mod plugin;
pub mod prelude;
pub mod queue;
pub mod router;
pub mod router {
use crate::event::Event;

pub trait Router: Send + Sync {
fn matches(&self, event: &dyn Event) -> bool;
}

impl<T> Router for T
where
T: Send + Sync + AsRef<str> + 'static,
{
fn matches(&self, event: &dyn Event) -> bool {
if let Ok(val) = event.content().downcast::<&str>() {
*val == self.as_ref()
} else {
false
}
}
}

mod command;
mod error;
mod logic;
mod matcher;

pub use command::CommandRouter;
pub use error::ErrorRouter;
pub use logic::{AllRouter, AnyRouter};
pub use matcher::{ContainsRouter, EndsWithRouter, ExactMatchRouter, StartsWithRouter};
}
pub mod runtime;
pub mod types;
221 changes: 0 additions & 221 deletions crates/aionbot-core/src/router.rs

This file was deleted.

82 changes: 82 additions & 0 deletions crates/aionbot-core/src/router/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use crate::event::Event;

use super::Router;

pub struct CommandRouter {
pub prefixes: Vec<String>,
pub command: Vec<String>,
}

impl Default for CommandRouter {
fn default() -> Self {
Self {
prefixes: vec!["/".into()],
command: ["help".into()].to_vec(),
}
}
}

impl CommandRouter {
pub fn new<S: Into<String>, C: IntoIterator<Item = S>>(
prefixes: Vec<String>,
command: C,
) -> Self {
Self {
prefixes,
command: command.into_iter().map(Into::into).collect(),
}
}

pub fn command<S: Into<String>, C: IntoIterator<Item = S>>(command: C) -> Self {
Self {
command: command.into_iter().map(Into::into).collect(),
..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 self.command.iter().any(|c| command.starts_with(c)) {
return true;
}
}
}
false
} else {
false
}
}
}

#[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", "command"]);
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(&"/command".to_string()));

let router = CommandRouter::new(vec!["!".to_string()], ["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()));
assert!(!router.matches(&"/cmd arg1 arg2".to_string()))
}
}
Loading

0 comments on commit 13c37fc

Please sign in to comment.