aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/actions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/actions.rs')
-rw-r--r--src/actions.rs121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/actions.rs b/src/actions.rs
new file mode 100644
index 0000000..bf78414
--- /dev/null
+++ b/src/actions.rs
@@ -0,0 +1,121 @@
+use std::fmt;
+
+use anyhow::Result;
+use async_trait::async_trait;
+use log::{debug, info, warn};
+use serde::Deserialize;
+
+use crate::message::MessageConfig;
+use crate::message::MessageParams;
+
+mod command;
+#[cfg(feature = "desktop")]
+mod desktop_notification;
+#[cfg(feature = "email")]
+mod email;
+#[cfg(feature = "nostr")]
+mod nostr;
+#[cfg(feature = "ntfy")]
+mod ntfy;
+#[cfg(feature = "telegram")]
+mod telegram;
+mod terminal_print;
+
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "snake_case")]
+#[serde(tag = "type")]
+pub enum AnyActionConfig {
+ TerminalPrint,
+ Command(self::command::CommandConfig),
+ #[cfg(feature = "desktop")]
+ DesktopNotification,
+ #[cfg(feature = "ntfy")]
+ Ntfy(self::ntfy::NtfyConfig),
+ #[cfg(feature = "email")]
+ Email(self::email::EmailConfig),
+ #[cfg(feature = "telegram")]
+ Telegram(self::telegram::TelegramConfig),
+ #[cfg(feature = "nostr")]
+ Nostr(self::nostr::NostrConfig),
+}
+
+impl fmt::Display for AnyActionConfig {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ AnyActionConfig::TerminalPrint => write!(f, "terminal_print"),
+ AnyActionConfig::Command(_) => write!(f, "command"),
+ #[cfg(feature = "desktop")]
+ AnyActionConfig::DesktopNotification => write!(f, "desktop_notification"),
+ #[cfg(feature = "ntfy")]
+ AnyActionConfig::Ntfy(_) => write!(f, "ntfy"),
+ #[cfg(feature = "email")]
+ AnyActionConfig::Email(_) => write!(f, "email"),
+ #[cfg(feature = "telegram")]
+ AnyActionConfig::Telegram(_) => write!(f, "telegram"),
+ #[cfg(feature = "nostr")]
+ AnyActionConfig::Nostr(_) => write!(f, "nostr"),
+ }
+ }
+}
+
+#[async_trait]
+pub trait Action<'a> {
+ async fn run(&self, params: Option<&MessageParams<'_, '_>>) -> Result<()>;
+}
+
+pub async fn get_action<'a>(
+ message_config: &'a MessageConfig,
+ action_config: &'a AnyActionConfig,
+) -> Result<Box<dyn Action<'a> + 'a + Sync>> {
+ Ok(match action_config {
+ AnyActionConfig::TerminalPrint => Box::new(self::terminal_print::TerminalPrintAction::new(
+ message_config,
+ )),
+ AnyActionConfig::Command(config) => {
+ Box::new(self::command::CommandAction::new(message_config, config)?)
+ }
+ #[cfg(feature = "desktop")]
+ AnyActionConfig::DesktopNotification => Box::new(
+ self::desktop_notification::DesktopNotificationAction::new(message_config),
+ ),
+ #[cfg(feature = "ntfy")]
+ AnyActionConfig::Ntfy(config) => {
+ Box::new(self::ntfy::NtfyAction::new(message_config, config)?)
+ }
+ #[cfg(feature = "email")]
+ AnyActionConfig::Email(config) => {
+ Box::new(self::email::EmailAction::new(message_config, config)?)
+ }
+ #[cfg(feature = "telegram")]
+ AnyActionConfig::Telegram(config) => {
+ Box::new(self::telegram::TelegramAction::new(message_config, config)?)
+ }
+ #[cfg(feature = "nostr")]
+ AnyActionConfig::Nostr(config) => {
+ Box::new(self::nostr::NostrAction::new(message_config, config).await?)
+ }
+ })
+}
+
+pub async fn get_actions<'a>(
+ message_config: &'a MessageConfig,
+ actions_config: &'a [AnyActionConfig],
+) -> Vec<Box<dyn Action<'a> + 'a + Sync>> {
+ let mut result: Vec<Box<dyn Action + Sync>> = Default::default();
+
+ // TODO: parallelize this. It's hard because the result vector needs to be shared.
+ for action_config in actions_config {
+ debug!("registering action '{}'", action_config);
+ match get_action(message_config, action_config).await {
+ Ok(action) => {
+ info!("registered action '{}'", action_config);
+ result.push(action);
+ }
+ Err(e) => {
+ warn!("could not register action '{}': {}", action_config, e);
+ }
+ }
+ }
+
+ result
+}