chore: lay out the ground work for a Discord command router

This commit is contained in:
2026-03-23 01:27:40 -04:00
parent abe6ff58ca
commit df6056d549
4 changed files with 115 additions and 23 deletions

63
Cargo.lock generated
View File

@@ -461,6 +461,16 @@ dependencies = [
"wyz",
]
[[package]]
name = "blart"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "220e5685b0a23b634e9215a69cfa9800e103ccd2f0134bd1a81cc9c584059701"
dependencies = [
"bytemuck",
"paste",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
@@ -1309,7 +1319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -1443,7 +1453,9 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
name = "fomo-reducer"
version = "0.1.0"
dependencies = [
"blart",
"clap",
"futures",
"opendal",
"rhai",
"rustls 0.23.35",
@@ -1502,9 +1514,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "futures"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
dependencies = [
"futures-channel",
"futures-core",
@@ -1517,9 +1529,9 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
dependencies = [
"futures-core",
"futures-sink",
@@ -1527,15 +1539,15 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-executor"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
dependencies = [
"futures-core",
"futures-task",
@@ -1555,9 +1567,9 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]]
name = "futures-lite"
@@ -1574,9 +1586,9 @@ dependencies = [
[[package]]
name = "futures-macro"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
dependencies = [
"proc-macro2",
"quote",
@@ -1596,21 +1608,21 @@ dependencies = [
[[package]]
name = "futures-sink"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
[[package]]
name = "futures-task"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
[[package]]
name = "futures-util"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
"futures-channel",
"futures-core",
@@ -1620,7 +1632,6 @@ dependencies = [
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
@@ -3587,6 +3598,12 @@ dependencies = [
"windows-link",
]
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "patricia_tree"
version = "0.8.0"
@@ -4553,7 +4570,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -5647,7 +5664,7 @@ dependencies = [
"getrandom 0.3.4",
"once_cell",
"rustix",
"windows-sys 0.52.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -6693,7 +6710,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.48.0",
"windows-sys 0.61.2",
]
[[package]]

View File

@@ -4,7 +4,9 @@ version = "0.1.0"
edition = "2024"
[dependencies]
blart = "0.4.0"
clap = { version = "4.5.40", features = ["derive", "env"] }
futures = "0.3.32"
opendal = { git = "https://github.com/apache/opendal", features = [
"services-azfile",
"services-aliyun-drive",

72
src/command/mod.rs Normal file
View File

@@ -0,0 +1,72 @@
use std::{
ffi::{CStr, CString},
fmt::Debug,
};
use blart::TreeMap;
use futures::future::BoxFuture;
use twilight_model::application::{
command::Command, interaction::application_command::CommandData,
};
#[derive(Debug, Clone)]
pub struct State {}
type Return = ();
type BoxedHandler = Box<dyn Fn(State, CommandData) -> BoxFuture<'static, Return>>;
fn box_handler<Handler, Fut>(handler: Handler) -> BoxedHandler
where
Fut: Future<Output = Return> + Send + 'static,
Handler: Fn(State, CommandData) -> Fut + 'static,
{
Box::new(move |state, command_data| Box::pin(handler(state, command_data)))
}
pub fn all() -> Vec<(&'static Command, BoxedHandler)> {
vec![]
}
#[derive(Default)]
pub struct Router {
map: TreeMap<CString, BoxedHandler>,
}
impl Router {
fn add_route<'s, 'a, Fut, Handler>(&'s mut self, name: &'a str, handler: Handler)
where
Fut: Future<Output = Return> + Send + 'static,
Handler: Fn(State, CommandData) -> Fut + 'static,
{
self.add_route_already_boxed(name, box_handler(handler));
}
fn add_route_already_boxed<'s, 'a>(&'s mut self, name: &'a str, boxed_handler: BoxedHandler) {
self.map.insert(name.parse().unwrap(), boxed_handler);
}
pub async fn handle(&self, args: State, command_data: CommandData) -> Return {
let name = &command_data.name;
let key = CStr::from_bytes_with_nul(name.as_bytes()).unwrap();
let handler = self
.map
.get(key)
.expect("asked to handle an inexistent command");
handler(args, command_data).await
}
}
impl<'a> FromIterator<(&'a CommandData, BoxedHandler)> for Router {
fn from_iter<T: IntoIterator<Item = (&'a CommandData, BoxedHandler)>>(iter: T) -> Self {
let mut router = Router::default();
for (command, handler) in iter {
let name = &command.name;
router.add_route(name, handler);
}
router
}
}

View File

@@ -1,3 +1,4 @@
mod command;
mod one_to_many;
mod one_to_many_with_data;
mod one_to_one;