mrsbfh

Matrix-Rust-SDK-Bot-Framework-Helper
git clone git://archive.git.mtrnord.blog/MTRNord/mrsbfh.git
Log | Files | Refs | README

commit 56ecf6569d11301af500f8489f318a1541841a03
parent 5e6cacc9baa2a6e21ca9573d8026c3d4877029cc
Author: MTRNord <mtrnord1@gmail.com>
Date:   Wed, 23 Feb 2022 22:29:30 +0100

Update documentation

Diffstat:
MREADME.md | 4+---
Mmrsbfh-macros/src/lib.rs | 3+--
Mmrsbfh/src/commands.rs | 71++++++++++++++++++++++++++++++++++++++++-------------------------------
Mmrsbfh/src/config.rs | 3+--
Mmrsbfh/src/errors.rs | 2++
Mmrsbfh/src/lib.rs | 12+++++++++---
Mmrsbfh/src/sync.rs | 14+++++++++++++-
Mmrsbfh/src/utils.rs | 51+++++----------------------------------------------
8 files changed, 72 insertions(+), 88 deletions(-)

diff --git a/README.md b/README.md @@ -13,11 +13,9 @@ A toolkit for writing commandbots more efficient in rust for matrix. To use it you need to add mrsbfh just like any regular create: ``` -mrsbfh = "0.4.0" +mrsbfh = "0.4.1" ``` After that there are the possible helpers available that are further described in the docs. -As there was no release yet, you can open them using `cargo doc -p mrsbfh --open` in any crate depending on it or after cloning the repository. - For a minimal example of the bot checkout the crate under the `example-bot` folder which is a minimal version of what is needed. diff --git a/mrsbfh-macros/src/lib.rs b/mrsbfh-macros/src/lib.rs @@ -57,7 +57,7 @@ pub fn command(args: TokenStream, input: TokenStream) -> TokenStream { /// } /// ``` /// -/// Note: The defined enum will NOT be present at runtime. It gets replaced fully +/// **Note**: The defined enum will NOT be present at runtime. It gets replaced fully #[proc_macro_attribute] pub fn command_generate(args: TokenStream, input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as syn::ItemEnum); @@ -214,7 +214,6 @@ pub fn config_derive(input: TokenStream) -> TokenStream { /// #[mrsbfh::commands::commands] /// async fn on_room_message(event: SyncMessageEvent<MessageEventContent>, room: Room) { /// // Your own logic. (Executed BEFORE the commands matching) -/// } /// } /// ``` /// diff --git a/mrsbfh/src/commands.rs b/mrsbfh/src/commands.rs @@ -1,4 +1,4 @@ -//! # Commands +//! # Helpers to construct Commands //! //! ## `#[command]` macro //! @@ -6,7 +6,7 @@ //! //! These functions require a specific syntax which is described below. //! -//! Also that function requires you to have a config struct which implements the [Config](crate::config::Config) +//! Also that function requires you to have a config struct which implements the [Loader](crate::config::Loader) //! trait. //! //! <br> @@ -17,18 +17,27 @@ //! In each of these submodules you can define a command like this: //! //! ```compile_fail -//! use matrix_sdk::events::{room::message::MessageEventContent, AnyMessageEventContent}; +//! use crate::config::Config; +//! use crate::errors::Error; +//! use matrix_sdk::ruma::events::{room::message::MessageEventContent, AnyMessageEventContent}; +//! use matrix_sdk::ruma::RoomId; +//! use matrix_sdk::Client; //! use mrsbfh::commands::command; -//! use mrsbfh::config::Config; -//! use std::error::Error; +//! use std::sync::Arc; +//! use tokio::sync::Mutex; //! //! #[command(help = "`!hello_world` - Prints \"hello world\".")] -//! pub async fn hello_world<C: Config>( +//! pub async fn hello_world<'a>( +//! _client: Client, //! tx: mrsbfh::Sender, -//! _config: C, +//! _config: Arc<Mutex<Config<'a>>>, //! _sender: String, +//! _room_id: RoomId, //! mut _args: Vec<&str>, -//! ) -> Result<(), Box<dyn Error>> { +//! ) -> Result<(), Error> +//! where +//! Config<'a>: mrsbfh::config::Loader + Clone, +//! { //! let content = //! AnyMessageEventContent::RoomMessage(MessageEventContent::notice_plain("Hello World!")); //! @@ -57,15 +66,15 @@ //! description = "This bot prints hello!" //! )] //! enum Commands { -//! HelloWorld +//! Hello_World //! } //! ``` //! //! This does generate a `match_command` function which takes the following arguments: //! -//! `(command: &str, config: C, tx: mrsbfh::Sender, sender: String, args: Vec<&str>)` +//! `(client: Client, tx: mrsbfh::Sender, config: Arc<Mutex<Config<'a>>>, sender: String, room_id: RoomId, args: Vec<&str>)` //! -//! and it returns: `Result<(), Box<dyn Error>>`. +//! and it returns: `Result<(), Error>` where Error is an Error struct you provide. //! //! This can either be called by you or you can continue reading and instead use another macro to //! do this for you. @@ -74,10 +83,10 @@ //! //! ## `#[commands]` macro //! -//! This macro is used to generate the logic in the [EventEmitter](matrix_sdk::EventEmitter) to +//! This macro is used to generate the logic in the [register_event_handler](matrix_sdk::Client::register_event_handler) method to //! handle commands after your code. //! -//! The usage is: +//! The definition is: //! //! ```compile_fail //! use crate::commands::match_command; @@ -88,35 +97,36 @@ //! room::message::MessageEventContent, //! SyncMessageEvent, //! }, -//! Client, EventEmitter, SyncRoom, +//! Client, SyncRoom, //! }; //! use tracing::*; //! -//! #[derive(Debug, Clone)] -//! pub struct Bot { -//! client: Client, -//! config: Config<'static>, -//! } //! //! #[mrsbfh::commands::commands] -//! #[async_trait] -//! impl EventEmitter for Bot { -//! async fn on_room_message(&self, room: SyncRoom, event: &SyncMessageEvent<MessageEventContent>) { -//! println!("message example") -//! } +//! pub(crate) async fn on_room_message( +//! event: SyncMessageEvent<MessageEventContent>, +//! room: Room, +//! client: Client, +//! config: Arc<Mutex<Config<'static>>>, +//! ) { +//! println!("message example") //! } //! ``` //! +//! You use it using this snippet: +//! +//! ``` +//! client +//! .register_event_handler(move |ev, room, client| { +//! sync::on_room_message(ev, room, client, config.clone()) +//! }) +//! .await; +//! ``` +//! //! <br> //! //! **This does have some requirements:** //! * Your `match_command` function MUST be imported -//! * The struct MUST have a field `config` which implements the [Config](crate::config::Config) -//! trait -//! * The struct MUST have a field `client` which is the [MatrixSDK Client](matrix_sdk::Client) -//! * The `#[async_trait]` macro MUST be below the `#[commands]` macro -//! * The `on_room_message` method MUST exist and the arguments MUST be named the way they are named -//! in the example. //! pub mod command_utils { @@ -130,5 +140,4 @@ pub mod command_utils { } } -#[cfg(feature = "macros")] pub use mrsbfh_macros::{command, command_generate, commands}; diff --git a/mrsbfh/src/config.rs b/mrsbfh/src/config.rs @@ -1,4 +1,4 @@ -//! # Config +//! # Helpers to construct a Config //! //! The Config Trait is used to be able to pass your Config to the commands as well as use them for //! the path of the session. @@ -36,7 +36,6 @@ use std::path::Path; use crate::errors::ConfigError; -#[cfg(feature = "macros")] pub use mrsbfh_macros::ConfigDerive; pub trait Loader { diff --git a/mrsbfh/src/errors.rs b/mrsbfh/src/errors.rs @@ -1,3 +1,5 @@ +//! # Errors that the helpers can return + use thiserror::Error; #[derive(Error, Debug)] diff --git a/mrsbfh/src/lib.rs b/mrsbfh/src/lib.rs @@ -16,20 +16,26 @@ //! * Macro for simple autojoin functionality //! * Macros for pretty defining of commands //! * Utils for a simple Config -//! * Utils for restoring ad saving matrix sessions +//! * Utils for restoring and saving matrix sessions //! //! ## Examples //! //! For examples please have a look at the [example-bot](https://github.com/MTRNord/mrsbfh/tree/main/example-bot) or take a look in the individual modules. +#[cfg(feature = "macros")] pub mod commands; + +#[cfg(feature = "macros")] pub mod config; + pub mod errors; pub mod sync; pub mod utils; +/// A wrapper type for the tokio sender channel with AnyMessageEventContent as content needed in multiple places pub type Sender = tokio::sync::mpsc::Sender<matrix_sdk::ruma::events::AnyMessageEventContent>; +/// An extension to simply do notices #[async_trait::async_trait] pub trait MatrixMessageExt { async fn send_notice( @@ -80,5 +86,6 @@ pub use tokio; pub use tracing; pub use url; +/// Used for generating the help text with macros #[cfg(feature = "macros")] -pub use pulldown_cmark; -\ No newline at end of file +pub use pulldown_cmark; diff --git a/mrsbfh/src/sync.rs b/mrsbfh/src/sync.rs @@ -1,3 +1,5 @@ +//! # Helpers for the sync process + use matrix_sdk::{ room::Room, ruma::events::{room::member::MemberEventContent, StrippedStateEvent}, @@ -5,6 +7,16 @@ use matrix_sdk::{ }; use tracing::*; +/// A small helper to auto join any incitation +/// +/// To join just do this: +/// ```compile_fail +/// client.register_event_handler(mrsbfh::sync::autojoin).await; +/// ``` +/// This will also automatically retry to join if that failed with increasing +/// delay between tries (numeber_of_tries*2) starting with a delay of 2. +/// It will print an error with the room id if the delay exceeds 3600s. +/// pub async fn autojoin( room_member: StrippedStateEvent<MemberEventContent>, client: Client, @@ -12,7 +24,7 @@ pub async fn autojoin( ) { // Autojoin logic if room_member.state_key != client.user_id().await.unwrap() { - warn!("Got invite that isn't for us"); + debug!("Got invite that isn't for us"); return; } if let matrix_sdk::room::Room::Invited(room) = room { diff --git a/mrsbfh/src/utils.rs b/mrsbfh/src/utils.rs @@ -1,4 +1,4 @@ -//! # Utils +//! # Various small Utils //! //! ## Session //! @@ -54,56 +54,13 @@ //! //! If not it creates and saves the [Session](crate::utils::Session) struct. Allowing for a relogin on the next start. //! -//! ## Autojoin -//! -//! The [`#[autojoin]`](crate::utils::autojoin) macro is used to generate the logic in the -//! [EventEmitter](matrix_sdk::EventEmitter) to handle invites for the bot. It is executed after your code. -//! -//! The usage is: -//! -//! ```compile_fail -//! use matrix_sdk::async_trait; -//! use matrix_sdk::{ -//! events::{ -//! room::message::MessageEventContent, StrippedStateEvent, -//! }, -//! EventEmitter, SyncRoom, Client -//! }; -//! use tracing::*; -//! -//! #[derive(Debug, Clone)] -//! pub struct Bot { -//! client: Client, -//! } -//! -//! #[mrsbfh::utils::autojoin] -//! #[async_trait] -//! impl EventEmitter for Bot { -//! async fn on_stripped_state_member( -//! &self, -//! room: SyncRoom, -//! room_member: &StrippedStateEvent<MemberEventContent>, -//! _: Option<MemberEventContent>, -//! ) { -//! println!("autojoin example") -//! } -//! } -//! ``` -//! -//! <br> -//! -//! **This does have some requirements:** -//! * The struct MUST have a field `client` which is the [MatrixSDK Client](matrix_sdk::Client) -//! * The `#[async_trait]` macro MUST be below the `#[autojoin]` macro -//! * The `on_stripped_state_member` method MUST exist and the arguments MUST be named the way they are named -//! in the example. -//! use crate::errors::SessionError; use serde::{Deserialize, Serialize}; use std::path::PathBuf; use tracing::*; +/// Informations needed to keep track about a session #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Session { /// The homeserver used for this session. @@ -117,15 +74,17 @@ pub struct Session { } impl Session { + /// Save the session to the specified path pub fn save(&self, session_path: PathBuf) -> Result<(), SessionError> { let mut session_path: PathBuf = session_path; - info!("SessionPath: {:?}", session_path); + debug!("SessionPath: {:?}", session_path); std::fs::create_dir_all(&session_path)?; session_path.push("session.json"); serde_json::to_writer(&std::fs::File::create(session_path)?, self)?; Ok(()) } + /// Load the session from a specified path pub fn load(session_path: PathBuf) -> Option<Self> { let mut session_path: PathBuf = session_path; session_path.push("session.json");