From 8309d26c9fa6d46437194bc329c308c58bd489dd Mon Sep 17 00:00:00 2001 From: Pierre de Lacroix Date: Fri, 26 Jun 2026 17:01:44 +0200 Subject: [PATCH] parse commands with clap --- Cargo.lock | 9 +++++- Cargo.toml | 1 + src/command.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 ++ src/serve/message.rs | 61 +++++++--------------------------------- 5 files changed, 88 insertions(+), 52 deletions(-) create mode 100644 src/command.rs diff --git a/Cargo.lock b/Cargo.lock index f1cfa4b..77e95d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -356,7 +356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", - "shlex", + "shlex 1.3.0", ] [[package]] @@ -3245,6 +3245,7 @@ dependencies = [ "rand 0.9.4", "serde", "serde_json", + "shlex 2.0.1", "simple_logger", "tokio", ] @@ -3255,6 +3256,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + [[package]] name = "signal-hook-registry" version = "1.4.8" diff --git a/Cargo.toml b/Cargo.toml index a44c664..a937ed8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,3 +20,4 @@ clap = { version = "^4.5", features = ["derive"] } log = "^0.4" simple_logger = "^5.2" either = "^1.15" +shlex = "2.0.1" diff --git a/src/command.rs b/src/command.rs new file mode 100644 index 0000000..70d4088 --- /dev/null +++ b/src/command.rs @@ -0,0 +1,67 @@ +use std::fmt::Write; + +use clap::{CommandFactory, Parser, Subcommand}; +use matrix_sdk::{Client, Room}; + +prelude! {} + +#[derive(Parser, Debug)] +#[command(version, about, name = "shifts")] +struct Clap { + #[command(subcommand)] + action: Action, +} + +#[derive(Debug, Subcommand)] +enum Action { + /// Lister les shifts + Lister, + /// Ajouter un shift + Ajouter { + /// Le nom du shift + nom: String, + /// Plus d'informations + infos: String, + }, + /// Obtenir de l'aide + Aide, +} + +/// Sends a message to a room. +pub async fn send_room_msg(_client: Client, room: Room, content: String) -> Res { + use matrix_sdk::ruma::events::room::message::RoomMessageEventContent; + // let md_parser = pulldown_cmark::Parser::new(&content); + // let mut html_body = String::with_capacity(250); + // pulldown_cmark::html::push_html(&mut html_body, md_parser); + // let content = RoomMessageEventContent::text_html(content, html_body); + let content = RoomMessageEventContent::text_plain(content); + let sent = room.send(content).await?; + Ok(sent.event_id) +} + +// pub fn handle(command: impl Into) -> Res<()> { +pub async fn handle(command: impl AsRef, room: Room, client: Client) -> Res<()> { + debug!("handling command: {}", command.as_ref()); + + let args = shlex::split(command.as_ref()).ok_or_else(lazyhow!("error: Invalid quoting"))?; + + let clap = Clap::try_parse_from(args)?; + + match clap.action { + Action::Lister => { + debug!("user asked for list"); + } + Action::Ajouter { nom, infos } => { + debug!("user asked for add"); + } + Action::Aide => { + debug!("user asked for help"); + let mut command = Clap::command(); + let help = command.render_long_help(); + debug!("{}", help); + send_room_msg(client, room, help.to_string()).await?; + } + } + + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index 0b5daa1..164e65d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,6 +39,8 @@ pub mod basic; pub mod serve; +pub mod command; + prelude! {} /// Warmup, runs before anything. diff --git a/src/serve/message.rs b/src/serve/message.rs index b223bd2..8da399a 100644 --- a/src/serve/message.rs +++ b/src/serve/message.rs @@ -14,11 +14,15 @@ details. */ use matrix_sdk::{ - Client, Room, RoomState, + Client, + Room, + RoomState, // event_handler::Ctx, ruma::events::room::message::{MessageType, OriginalSyncRoomMessageEvent}, }; +use crate::command; + prelude! {} /// Handle room messages. @@ -55,49 +59,10 @@ pub async fn on_room_message( return Ok(()); }; - let mut body = text_content.body.as_str(); + let body = text_content.body.as_str(); - // If not in a private room, ignore messages that don't start with our name optionally followed - // by `:`. - if !room.is_direct().await? { - let Some(my_id) = client.user_id() else { - warn!("failed to retrieve my own identifier, ignoring message"); - return Ok(()); - }; - if let Some(mentions) = event.content.mentions { - if !mentions.user_ids.contains(my_id) { - debug!("ignoring message in non-direct room that does not mention me"); - return Ok(()); - } - } else { - debug!("ignoring message in non-direct room with no mentions"); - return Ok(()); - } - let account = client.account(); - let pref = if let Ok(Some(display_name)) = account.get_display_name().await { - display_name - } else if let Some(id) = client.user_id() { - id.to_string() - } else { - warn!( - "failed to retrieve display name AND user identifier, \ - ignoring non-direct room message" - ); - return Ok(()); - }; - // debug!("my prefix is `{}`\nmessage body:\n```\n{}\n```", pref, body); - if body.starts_with(&pref) { - info!("dropping id prefix"); - body = body[pref.len()..].trim(); - // debug!("updated message body:\n```\n{}\n```", body); - if body.starts_with(':') { - body = body[1..].trim(); - // debug!("updated message body (final):\n```\n{}\n```", body); - } - } else { - debug!("ignoring message in non-direct room that does not start with a tag to myself"); - return Ok(()); - } + if !body.starts_with("!") { + return Ok(()); } let room_name = match room @@ -119,14 +84,8 @@ pub async fn on_room_message( event.sender, text_content.body, body ); - // let room = munity::Room::new(room.room_id())?; - // let user = munity::User::new(event.sender.to_string())?; - // let event = munity::Event::new(event.event_id.to_string())?; - // let message = munity::Message::new(user.clone(), event); - // let source = munity::Thread::new(room, message); - // let msg = munity::InMsg::Com(munity::InComMsg::new(user, source, body)); - // in_msg_sender.send(msg).await?; - // debug!("message successfully sent"); + command::handle(body, room, client).await?; + debug!("message successfully sent"); Ok(()) }