commit c148d48597648bca8b97bc550d55d35a1fb5899e
parent 77bbd2f7ae2f5eda963d5fff76d8eb049ffaae44
Author: Jonas Platte <jplatte+git@posteo.de>
Date: Sun, 21 Jul 2019 11:58:35 +0200
Add anymap for state handling
Diffstat:
5 files changed, 66 insertions(+), 7 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
@@ -4,6 +4,9 @@ version = "0.1.0"
authors = ["Jonas Platte <jplatte+git@posteo.de>"]
edition = "2018"
+[dependencies]
+anymap = "0.12.1"
+
[dependencies.ruma-bot-macro]
path = "macro"
diff --git a/macro/src/lib.rs b/macro/src/lib.rs
@@ -31,6 +31,10 @@ pub fn command_handler(args: TokenStream, input: TokenStream) -> TokenStream {
fn commands(&self) -> &'static [&'static str] {
&[#(#commands),*]
}
+
+ fn get_fn(&self) -> Box<dyn ruma_bot::CommandHandlerFn> {
+ unimplemented!()
+ }
}
})
}
diff --git a/src/lib.rs b/src/lib.rs
@@ -10,17 +10,27 @@
use std::{collections::HashMap, sync::Arc};
+use anymap::any::Any;
+type AnyMap = anymap::Map<dyn Any + Send + Sync>;
+
pub use ruma_bot_macro::command_handler;
-/// An `async fn` annotated with `#[ruma_bot::command_handler]
+mod state;
+
+/// A function (usually `async`) annotated with `#[ruma_bot::command_handler]
pub trait CommandHandler {
/// The command(s) this function handles
fn commands(&self) -> &'static [&'static str];
+
+ fn get_fn(&self) -> Box<dyn CommandHandlerFn>;
+}
+
+pub trait CommandHandlerFn: Send + Sync {
+ //fn
}
-#[derive(Clone)]
pub struct BotBuilder {
- handlers: HashMap<&'static str, &'static dyn CommandHandler>,
+ handlers: HashMap<&'static str, Box<dyn CommandHandlerFn>>,
}
impl BotBuilder {
@@ -31,9 +41,9 @@ impl BotBuilder {
}
/// Register a command handler
- pub fn register(mut self, handler: &'static dyn CommandHandler) -> Self {
+ pub fn register(mut self, handler: impl CommandHandler) -> Self {
for command in handler.commands() {
- let _old_value = self.handlers.insert(command, handler);
+ let _old_value = self.handlers.insert(command, handler.get_fn());
// TODO: Log a warning if _old_value is Some
}
@@ -43,12 +53,14 @@ impl BotBuilder {
pub fn build(self) -> Bot {
Bot {
handlers: Arc::new(self.handlers),
+ state: AnyMap::new(),
}
}
}
pub struct Bot {
- handlers: Arc<HashMap<&'static str, &'static dyn CommandHandler>>,
+ handlers: Arc<HashMap<&'static str, Box<dyn CommandHandlerFn>>>,
+ state: AnyMap,
}
impl Bot {
@@ -56,3 +68,15 @@ impl Bot {
Ok(())
}
}
+
+#[allow(dead_code)]
+mod compile_tests {
+ use super::Bot;
+
+ fn send_sync() {
+ fn assert_send<T: Send>() {}
+ fn assert_sync<T: Send>() {}
+ assert_send::<Bot>();
+ assert_sync::<Bot>();
+ }
+}
diff --git a/src/state.rs b/src/state.rs
@@ -0,0 +1,28 @@
+use std::{
+ fmt::{self, Debug},
+ ops::Deref,
+};
+
+struct State<T: Send + Sync> {
+ inner: T,
+}
+
+impl<T> Debug for State<T>
+where
+ T: Debug + Send + Sync,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{:?}", self.inner)
+ }
+}
+
+impl<T> Deref for State<T>
+where
+ T: Send + Sync,
+{
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &self.inner
+ }
+}
diff --git a/tests/echo.rs b/tests/echo.rs
@@ -7,5 +7,5 @@ async fn help() {}
#[tokio::main]
async fn main() {
- let bot = BotBuilder::new().register(&help).build();
+ let bot = BotBuilder::new().register(help).build();
}