commit 79417cefc3ad6844277860c8931655b237fba83c
parent d7ca0ac94f9ac467f54f4e3d7967fbd5e6955f21
Author: MTRNord <mtrnord1@gmail.com>
Date: Thu, 7 Jan 2021 21:11:56 +0100
chore: Add docs everywhere
Diffstat:
5 files changed, 285 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
@@ -1,5 +1,11 @@
# MRSBFH - Matrix-Rust-SDK-Bot-Framework-Helper
+[<img alt="github" src="https://img.shields.io/badge/github-MTRNord/mrsbfh-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/MTRNord/mrsbfh)
+[<img alt="crates.io" src="https://img.shields.io/crates/v/mrsbfh.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/mrsbfh)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-mrsbfh-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/mrsbfh)
+<!--[<img alt="build status" src="https://img.shields.io/github/workflow/status/MTRNord/mrsbfh/CI/master?style=for-the-badge" height="20">](https://github.com/MTRNord/mrsbfh/actions?query=branch%3Amaster)-->
+
+
A toolkit for writing commandbots more efficient in rust for matrix.
## How to use
@@ -12,6 +18,6 @@ mrsbfh = {git = "https://github.com/MTRNord/mrsbfh"}
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.
+As there was no release yet, you can open them using `cargo +nigtly 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/src/commands.rs b/mrsbfh/src/commands.rs
@@ -1 +1,122 @@
+//! # Commands
+//!
+//! ## `#[command]` macro
+//!
+//! Commands are defined in their own submodules using a function which name defines the command name.
+//!
+//! 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)
+//! trait.
+//!
+//! <br>
+//!
+//! To use the commands macros you want a module where these commands are stored in. This is because
+//! each is REQUIRED to be in a submodule with the SAME name as the commands name.
+//!
+//! In each of these submodules you can define a command like this:
+//!
+//! ```compile_fail
+//! use matrix_sdk::events::{room::message::MessageEventContent, AnyMessageEventContent};
+//! use mrsbfh::commands::command;
+//! use mrsbfh::config::Config;
+//! use std::error::Error;
+//!
+//! #[command(help = "`!hello_world` - Prints \"hello world\".")]
+//! pub async fn hello_world<C: Config>(
+//! tx: mrsbfh::Sender,
+//! _config: C,
+//! _sender: String,
+//! mut _args: Vec<&str>,
+//! ) -> Result<(), Box<dyn Error>> {
+//! let content =
+//! AnyMessageEventContent::RoomMessage(MessageEventContent::notice_plain("Hello World!"));
+//!
+//! tx.send(content).await?;
+//! Ok(())
+//! }
+//! ```
+//!
+//! <br>
+//!
+//! ## `#[command_generate]` macro
+//!
+//! You can now either build your own match statement and help or to make this more convenient you
+//! can use the `command_generate` macro to do this for you.
+//!
+//! To use it you are required to have the following code structure inside the file that is the
+//! direct parent module of the commands.
+//!
+//! ```compile_fail
+//! use mrsbfh::commands::command_generate;
+//!
+//! pub mod hello_world;
+//!
+//! #[command_generate(
+//! bot_name = "Example",
+//! description = "This bot prints hello!"
+//! )]
+//! enum Commands {
+//! HelloWorld
+//! }
+//! ```
+//!
+//! This does generate a `match_command` function which takes the following arguments:
+//!
+//! `(command: &str, config: C, tx: mrsbfh::Sender, sender: String, args: Vec<&str>)`
+//!
+//! and it returns: `Result<(), Box<dyn Error>>`.
+//!
+//! This can either be called by you or you can continue reading and instead use another macro to
+//! do this for you.
+//!
+//! <br>
+//!
+//! ## `#[commands]` macro
+//!
+//! This macro is used to generate the logic in the [EventEmitter](matrix_sdk::EventEmitter) to
+//! handle commands after your code.
+//!
+//! The usage is:
+//!
+//! ```compile_fail
+//! use crate::commands::match_command;
+//! use crate::config::Config;
+//! use matrix_sdk::async_trait;
+//! use matrix_sdk::{
+//! events::{
+//! room::message::MessageEventContent,
+//! SyncMessageEvent,
+//! },
+//! Client, EventEmitter, 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")
+//! }
+//! }
+//! ```
+//!
+//! <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 use mrsbfh_macros::{command, command_generate, commands};
diff --git a/mrsbfh/src/config.rs b/mrsbfh/src/config.rs
@@ -1,3 +1,35 @@
+//! # 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.
+//!
+//! <br>
+//!
+//! The simplest way is to use the Derive macro [`#[derive(ConfigDerive)]`](crate::config::ConfigDerive)
+//!
+//! It requires however that You also derive [Clone](std::clone::Clone), [Serialize](serde::Serialize)
+//! and [Deserialize](serde::Deserialize).
+//!
+//! Also this only works for yaml config files. For any other format you will to implement the trait
+//! yourself. However the crate still needs to implement [Clone](std::clone::Clone).
+//!
+//! ## Example
+//!
+//! ```compile_fail
+//! use serde::{Deserialize, Serialize};
+//! use std::borrow::Cow;
+//!
+//! #[derive(Debug, PartialEq, Serialize, Deserialize, Clone, ConfigDerive)]
+//! pub struct Config<'a> {
+//! pub homeserver_url: Cow<'a, str>,
+//! pub mxid: Cow<'a, str>,
+//! pub password: Cow<'a, str>,
+//! pub store_path: Cow<'a, str>,
+//! pub session_path: Cow<'a, str>,
+//! }
+//! ```
+//!
+
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::error::Error;
diff --git a/mrsbfh/src/lib.rs b/mrsbfh/src/lib.rs
@@ -1,3 +1,27 @@
+//! [![github]](https://github.com/MTRNord/mrsbfh) [![crates-io]](https://crates.io/crates/mrsbfh) [![docs-rs]](crate)
+//!
+//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
+//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
+//!
+//! <br>
+//!
+//! # MRSBFH - Matrix-Rust-SDK-Bot-Framework-Helper
+//!
+//! `mrsbfh` is a collection of utilities to make performing certain tasks in command bots
+//! with matrix easier.
+//!
+//! ## Features
+//!
+//! * Macro for simple autojoin functionality
+//! * Macros for pretty defining of commands
+//! * Utils for a simple Config
+//! * Utils for restoring ad 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.
+
pub mod commands;
pub mod config;
pub mod utils;
diff --git a/mrsbfh/src/utils.rs b/mrsbfh/src/utils.rs
@@ -1,3 +1,104 @@
+//! # Utils
+//!
+//! ## Session
+//!
+//! The easiest way to use the [Session](crate::utils::Session) struct is to use it like this:
+//!
+//! ```compile_fail
+//! use matrix_sdk::Session as SDKSession;
+//!
+//! if let Some(session) = Session::load(config.session_path.parse().unwrap()) {
+//! info!("Starting relogin");
+//!
+//! let session = SDKSession {
+//! access_token: session.access_token,
+//! device_id: session.device_id.into(),
+//! user_id: matrix_sdk::identifiers::UserId::try_from(session.user_id.as_str()).unwrap(),
+//! };
+//!
+//! if let Err(e) = client.restore_login(session).await {
+//! error!("{}", e);
+//! };
+//! info!("Finished relogin");
+//! } else {
+//! info!("Starting login");
+//! let login_response = client
+//! .login(
+//! &config.mxid,
+//! &config.password,
+//! None,
+//! Some(&"timetracking-bot".to_string()),
+//! )
+//! .await;
+//! match login_response {
+//! Ok(login_response) => {
+//! info!("Session: {:#?}", login_response);
+//! let session = Session {
+//! homeserver: client.homeserver().to_string(),
+//! user_id: login_response.user_id.to_string(),
+//! access_token: login_response.access_token,
+//! device_id: login_response.device_id.into(),
+//! };
+//! session.save(config.session_path.parse().unwrap())?;
+//! }
+//! Err(e) => error!("Error while login: {}", e),
+//! }
+//! info!("Finished login");
+//! }
+//! ```
+//!
+//! <br>
+//!
+//! This first checks if there is a session already existing and uses it to relogin using the known
+//! session data.
+//!
+//! 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 serde::{Deserialize, Serialize};
use std::error::Error;
use std::path::PathBuf;