parse commands with clap

This commit is contained in:
Pierre de Lacroix 2026-06-26 17:01:44 +02:00
parent f83fded289
commit 8309d26c9f
Signed by: lateralus23
GPG key ID: 53E0CEC29C24EF39
5 changed files with 88 additions and 52 deletions

67
src/command.rs Normal file
View file

@ -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<OwnedEventId> {
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<String>) -> Res<()> {
pub async fn handle(command: impl AsRef<str>, 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(())
}

View file

@ -39,6 +39,8 @@ pub mod basic;
pub mod serve;
pub mod command;
prelude! {}
/// Warmup, runs before anything.

View file

@ -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 `<ws>:<ws>`.
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(())
}