Add macro for extracting arguments

This commit is contained in:
jude 2024-02-16 20:09:32 +00:00
parent b81c3c80c1
commit d0833b7bca
2 changed files with 60 additions and 37 deletions

View File

@ -38,3 +38,13 @@ SELECT
WHERE m1.id = m2.id WHERE m1.id = m2.id
) )
FROM macro m1; 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

View File

@ -11,56 +11,69 @@ pub enum RecordedCommand {
Remind(RemindOptions), 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<String>) => {
$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<Tz>) => {
$ctx.args
.iter()
.find(|opt| opt.name == $name)
.map(|opt| &opt.value)
.map(|v| match v {
ResolvedValue::String(s) => s.parse::<Tz>().ok(),
_ => None,
})
.flatten()
};
}
impl RecordedCommand { impl RecordedCommand {
pub fn from_context(ctx: ApplicationContext) -> Option<Self> { pub fn from_context(ctx: ApplicationContext) -> Option<Self> {
match ctx.command().identifying_name.as_str() { match ctx.command().identifying_name.as_str() {
"remind" => Some(Self::Remind(RemindOptions { "remind" => Some(Self::Remind(RemindOptions {
time: ctx time: extract_arg!(ctx, "time", String),
.args content: extract_arg!(ctx, "content", String),
.iter() channels: extract_arg!(ctx, "channels", Option<String>),
.find(|opt| opt.name == "time") interval: extract_arg!(ctx, "interval", Option<String>),
.map(|opt| &opt.value) expires: extract_arg!(ctx, "expires", Option<String>),
.map_or_else( tts: extract_arg!(ctx, "tts", bool),
|| String::new(), timezone: extract_arg!(ctx, "timezone", Option<Tz>),
|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,
})), })),
_ => None, _ => None,
} }
} }
pub async fn execute(&self, ctx: ApplicationContext<'_>) -> Result<(), Error> { pub async fn execute(self, ctx: ApplicationContext<'_>) -> Result<(), Error> {
match self { match self {
RecordedCommand::Remind(command_options) => { RecordedCommand::Remind(command_options) => {
create_reminder( create_reminder(
Context::Application(ctx), Context::Application(ctx),
command_options.time.clone(), command_options.time,
command_options.content.clone(), command_options.content,
None, command_options.channels,
None, command_options.interval,
None, command_options.expires,
None, command_options.tts,
None, command_options.timezone,
) )
.await .await
} }