From d0833b7bcaa600cab17d4de39b2ef9fd961f6193 Mon Sep 17 00:00:00 2001 From: jude Date: Fri, 16 Feb 2024 20:09:32 +0000 Subject: [PATCH] Add macro for extracting arguments --- .../20240210133900_macro_restructure.sql | 10 +++ src/models/command_macro.rs | 87 +++++++++++-------- 2 files changed, 60 insertions(+), 37 deletions(-) diff --git a/migrations/20240210133900_macro_restructure.sql b/migrations/20240210133900_macro_restructure.sql index b513b3f..809f73b 100644 --- a/migrations/20240210133900_macro_restructure.sql +++ b/migrations/20240210133900_macro_restructure.sql @@ -38,3 +38,13 @@ SELECT WHERE m1.id = m2.id ) FROM macro m1; + +# # Check which commands are used in macros +# SELECT DISTINCT command_name +# FROM macro m2 +# JOIN JSON_TABLE( +# commands, +# '$[*]' COLUMNS ( +# command_name VARCHAR(64) PATH '$.command_name' ERROR ON ERROR, +# options JSON PATH '$.options' ERROR ON ERROR +# )) AS t1 diff --git a/src/models/command_macro.rs b/src/models/command_macro.rs index 22d0dbd..7027fcb 100644 --- a/src/models/command_macro.rs +++ b/src/models/command_macro.rs @@ -11,56 +11,69 @@ pub enum RecordedCommand { Remind(RemindOptions), } +macro_rules! extract_arg { + ($ctx:ident, $name:literal, String) => { + $ctx.args.iter().find(|opt| opt.name == $name).map(|opt| &opt.value).map_or_else( + || String::new(), + |v| match v { + ResolvedValue::String(s) => s.to_string(), + _ => String::new(), + }, + ) + }; + ($ctx:ident, $name:literal, Option) => { + $ctx.args.iter().find(|opt| opt.name == $name).map(|opt| &opt.value).map(|v| match v { + ResolvedValue::String(s) => s.to_string(), + _ => String::new(), + }) + }; + ($ctx:ident, $name:literal, bool) => { + $ctx.args.iter().find(|opt| opt.name == $name).map(|opt| &opt.value).map(|v| match v { + ResolvedValue::Boolean(b) => b.to_owned(), + _ => false, + }) + }; + ($ctx:ident, $name:literal, Option) => { + $ctx.args + .iter() + .find(|opt| opt.name == $name) + .map(|opt| &opt.value) + .map(|v| match v { + ResolvedValue::String(s) => s.parse::().ok(), + _ => None, + }) + .flatten() + }; +} + impl RecordedCommand { pub fn from_context(ctx: ApplicationContext) -> Option { match ctx.command().identifying_name.as_str() { "remind" => Some(Self::Remind(RemindOptions { - time: ctx - .args - .iter() - .find(|opt| opt.name == "time") - .map(|opt| &opt.value) - .map_or_else( - || String::new(), - |v| match v { - ResolvedValue::String(s) => s.to_string(), - _ => String::new(), - }, - ), - content: ctx - .args - .iter() - .find(|opt| opt.name == "content") - .map(|opt| &opt.value) - .map_or_else( - || String::new(), - |v| match v { - ResolvedValue::String(s) => s.to_string(), - _ => String::new(), - }, - ), - channels: None, - interval: None, - expires: None, - tts: None, - timezone: None, + time: extract_arg!(ctx, "time", String), + content: extract_arg!(ctx, "content", String), + channels: extract_arg!(ctx, "channels", Option), + interval: extract_arg!(ctx, "interval", Option), + expires: extract_arg!(ctx, "expires", Option), + tts: extract_arg!(ctx, "tts", bool), + timezone: extract_arg!(ctx, "timezone", Option), })), _ => None, } } - pub async fn execute(&self, ctx: ApplicationContext<'_>) -> Result<(), Error> { + pub async fn execute(self, ctx: ApplicationContext<'_>) -> Result<(), Error> { match self { RecordedCommand::Remind(command_options) => { create_reminder( Context::Application(ctx), - command_options.time.clone(), - command_options.content.clone(), - None, - None, - None, - None, - None, + command_options.time, + command_options.content, + command_options.channels, + command_options.interval, + command_options.expires, + command_options.tts, + command_options.timezone, ) .await }