/*
* Copyright (C) 2025 Jonni Liljamo <jonni@liljamo.com>
*
* This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for
* more information.
*/
use async_trait::async_trait;
use pastey::paste;
use crate::{MessageForm, config::ServiceConfig};
pub mod gotify;
pub mod matrix;
#[async_trait]
pub trait Service {
async fn send(&self, form: &MessageForm) -> Result<(), Box<dyn std::error::Error>>;
}
macro_rules! make_service_match {
($client:expr, $service_config:expr, $service:expr) => {
paste! {
Box::new($service::[<$service:upper_camel Service>]::new(
$client,
$service_config
.as_any()
.downcast_ref::<$service::[<$service:upper_camel Config>]>()
.ok_or("no such service")?.clone(),
)?)
}
};
($client:expr, $service_config:expr, $($service:expr),+) => {
match $service_config.typetag_name() {
$(stringify!($service) => make_service_match!($client, $service_config, $service)),+,
_ => unreachable!(),
}
};
}
pub fn build(
client: reqwest::Client,
service_config: &dyn ServiceConfig,
) -> Result<Box<dyn Service + Send + Sync>, Box<dyn std::error::Error>> {
let config: Box<dyn Service + Send + Sync> =
make_service_match!(client, service_config, gotify, matrix);
Ok(config)
}