ruma-bot

git clone git://archive.git.mtrnord.blog/MTRNord/ruma-bot.git
Log | Files | Refs

commit 46db0392b4ca37cc17e2bfd7fd52829adb1942eb
parent e6ba2f4a0df9b95e118edd43b96478305c956ead
Author: Jonas Platte <jplatte+git@posteo.de>
Date:   Tue,  6 Aug 2019 21:49:51 +0200

Add Debug implementations, docs

Diffstat:
Asrc/debug.rs | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib.rs | 36+++++++++++++++++++++++-------------
Msrc/util.rs | 7+++++--
Msrc/wrap.rs | 20+++-----------------
4 files changed, 89 insertions(+), 32 deletions(-)

diff --git a/src/debug.rs b/src/debug.rs @@ -0,0 +1,58 @@ +use std::fmt; + +use crate::{Bot, BotBuilder, HandlerFnMap, MsgContent, State}; + +struct Placeholder; + +impl fmt::Debug for Placeholder { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("[...]") + } +} + +struct HandlerFnMapDbg<'a>(&'a HandlerFnMap); + +impl<'a> fmt::Debug for HandlerFnMapDbg<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_map() + .entries(self.0.iter().map(|(k, _)| (k, Placeholder))) + .finish() + } +} + +impl fmt::Debug for BotBuilder { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("BotBuilder") + .field("handlers", &HandlerFnMapDbg(&self.handlers)) + .field("homeserver_url", &self.homeserver_url) + .field("username", &self.username) + .field("password", &Placeholder) + .finish() + } +} + +impl fmt::Debug for Bot { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Bot") + .field("client", &self.client) + .field("handlers", &HandlerFnMapDbg(&self.handlers)) + .field("state", &self.state) + .field("connection_details", &self.connection_details) + .finish() + } +} + +impl<T> fmt::Debug for State<T> +where + T: fmt::Debug + Send + Sync, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.0) + } +} + +impl fmt::Debug for MsgContent { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.0) + } +} diff --git a/src/lib.rs b/src/lib.rs @@ -6,7 +6,7 @@ //! [matrix]: https://matrix.org/ #![feature(async_await)] -//#![warn(missing_debug_implementations, missing_docs)] +#![warn(missing_debug_implementations, missing_docs)] use std::{collections::HashMap, pin::Pin, sync::Arc}; @@ -22,6 +22,7 @@ type HandlerFnMap = HashMap<&'static str, Box<dyn CommandHandler>>; pub use ruma_bot_macros::command_handler; +mod debug; mod util; mod wrap; @@ -50,13 +51,14 @@ pub trait CommandHandler: Send + Sync { fn handle(&self, _: &Bot, msg_content: &str) -> Pin<Box<dyn Future<Output = ()> + Send>>; } -#[derive(Clone)] +#[derive(Clone, Debug)] struct ConnectionDetails { //homeserver_url: Url, username: String, password: String, } +/// A builder that the `Bot` type pub struct BotBuilder { handlers: HandlerFnMap, homeserver_url: Option<Url>, @@ -65,6 +67,7 @@ pub struct BotBuilder { } impl BotBuilder { + /// Crate a new `BotBuilder` pub fn new() -> Self { Self { handlers: HashMap::new(), @@ -91,21 +94,34 @@ impl BotBuilder { self } + /// Set the homeserver url (must be an `https` url currently) + /// + /// If the homeserver url is not set with this method, `build` will fall back to the environment + /// variable `RUMA_BOT_HOMESERVER_URL`. pub fn homeserver_url(mut self, homeserver_url: Url) -> Self { self.homeserver_url = Some(homeserver_url); self } + /// Set the username + /// + /// If the username is not set with this method, `build` will fall back to the environment + /// variable `RUMA_BOT_USERNAME`. pub fn username(mut self, username: String) -> Self { self.username = Some(username); self } + /// Set the password + /// + /// If the password is not set with this method, ,`build` will fall back to the environment + /// variable `RUMA_BOT_PASSWORD`. pub fn password(mut self, password: String) -> Self { self.password = Some(password); self } + /// Build the bot pub fn build(self) -> Fallible<Bot> { Ok(Bot { client: MatrixClient::https( @@ -133,6 +149,8 @@ impl BotBuilder { } } +/// A bot, usually containing one or more command handlers and optionally a reaction handler, +/// which can also manage arbitrary application data (one instance per type). #[derive(Clone)] pub struct Bot { client: MatrixClient, @@ -142,6 +160,7 @@ pub struct Bot { } impl Bot { + /// Start the Bot's main loop pub async fn run(mut self) -> Result<(), ruma_client::Error> { use api::r0::{ filter::{Filter, FilterDefinition, RoomEventFilter, RoomFilter}, @@ -157,12 +176,8 @@ impl Bot { // .unwrap() will never fail. let cd = self.connection_details.take().unwrap(); - print!("logging in... "); - self.client.log_in(cd.username, cd.password, None).await?; - println!("done!"); - let mut sync0 = Box::pin(self.client.sync( Some(SyncFilter::FilterDefinition(FilterDefinition::ignore_all())), None, @@ -175,7 +190,6 @@ impl Bot { account_data: Some(Filter::ignore_all()), room: Some(RoomFilter { account_data: Some(RoomEventFilter::ignore_all()), - ephemeral: Some(RoomEventFilter::ignore_all()), state: Some(RoomEventFilter::ignore_all()), ..Default::default() }), @@ -186,20 +200,16 @@ impl Bot { true, )); - println!("initial sync finished!"); - while let Some(res) = sync_stream.try_next().await? { - for (room_id, room) in res.rooms.join { + for (_room_id, room) in res.rooms.join { for event in room.timeline.events { // Filter out the text messages if let RoomEvent::RoomMessage(MessageEvent { content: MessageEventContent::Text(TextMessageEventContent { body, .. }), - sender, + sender: _sender, .. }) = event { - println!("received message `{}`", body); - if body.starts_with('!') { if let Some(idx) = body.find(char::is_whitespace) { let command = &body[1..idx]; diff --git a/src/util.rs b/src/util.rs @@ -1,7 +1,10 @@ +// This module is not public, and all exports from it are #[doc(hidden)], so the docs wouldn't be +// visible anyway. +#![allow(missing_docs)] + use crate::{Bot, MsgContent, State}; -// Currently, GetParam could also be implemented direclty on &'a Bot, but in the future, -// event-specific data will be added to this struct. +#[derive(Debug)] pub struct HandlerParamMatcher<'a> { pub bot: &'a Bot, pub msg_content: &'a str, diff --git a/src/wrap.rs b/src/wrap.rs @@ -1,21 +1,7 @@ -use std::{ - fmt::{self, Debug}, - ops::Deref, -}; +use std::ops::Deref; #[derive(Clone, Copy)] -pub 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) - } -} +pub struct State<T: Send + Sync>(pub(crate) T); impl<T> Deref for State<T> where @@ -24,7 +10,7 @@ where type Target = T; fn deref(&self) -> &T { - &self.inner + &self.0 } }