use core::fmt;
use std::{collections::HashMap, error::Error};
use serde::{Deserialize, Serialize};
use crate::configuration::{
email::EmailEventBody,
push::{ProvidersConfig, PushEventBody},
request::{RequestEvent, RequestEventBody},
};
pub mod email;
pub mod push;
pub mod request;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CommonEvent<T> {
pub template_path: String,
pub default_params: Option<T>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct WebhookDto {
pub email: Option<EmailEventBody>,
pub push: Option<PushEventBody>,
pub request: Option<RequestEventBody>,
pub automation: Option<RequestEventBody>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Config {
pub tenant_id: String,
pub email: Option<HashMap<String, CommonEvent<EmailEventBody>>>,
pub push: Option<HashMap<String, CommonEvent<PushEventBody>>>,
pub request: Option<HashMap<String, RequestEvent>>,
pub config: Option<Configuration>,
pub webhooks: HashMap<String, WebhookActionSettings>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Configuration {
push: Option<ProvidersConfig>,
}
#[derive(Default)]
pub struct TenantConfig(HashMap<String, Config>);
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct WebhookActionSettings {
pub request: Option<RequestEvent>,
pub email: Option<CommonEvent<EmailEventBody>>,
pub push: Option<CommonEvent<PushEventBody>>,
pub automation: Option<RequestEvent>,
}
pub enum WebhookAction {
Request(Option<RequestEvent>),
Automation(Option<RequestEvent>),
Email(Option<CommonEvent<EmailEventBody>>),
Push(Option<CommonEvent<PushEventBody>>),
}
impl Config {
pub fn get_email_actions(self) -> Vec<String> {
self.email.unwrap_or_default().into_keys().collect()
}
pub fn get_template_by_email_action(self, action: String) -> String {
self.email
.unwrap_or_default()
.get(&action)
.unwrap()
.template_path
.clone()
}
pub fn get_expo_access_token(self) -> Result<String, TenantConfigError> {
if self.config.is_none() {
return Err(TenantConfigError::ExtraConfigMissing);
}
let unwrapped_config = self.config.unwrap();
if unwrapped_config.push.is_none() {
return Err(TenantConfigError::ExtraConfigPushSettingsMissing);
}
let unwrapped_push_settings = unwrapped_config.push.unwrap();
if unwrapped_push_settings.expo.is_none() {
return Err(TenantConfigError::ExtraConfigPushSettingsMissing);
}
Ok(unwrapped_push_settings.expo.unwrap().access_token)
}
}
#[derive(Debug)]
pub enum TenantConfigError {
Missing,
WrongStructure,
WebhookActionSettingsMissing,
WebhookRequestActionMissing,
WebhookPushActionMissing,
WebhookEmailActionMissing,
ExtraConfigExpoTokenMissing,
ExtraConfigPushSettingsMissing,
ExtraConfigMissing,
}
impl fmt::Display for TenantConfigError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TenantConfigError::Missing => write!(f, "Tenant configuration is missing"),
TenantConfigError::WebhookActionSettingsMissing => {
write!(f, "Webhook action settings is missing")
}
TenantConfigError::WebhookEmailActionMissing => {
write!(f, "Webhook email action is missing")
}
TenantConfigError::WebhookPushActionMissing => {
write!(f, "Webhook push action is missing")
}
TenantConfigError::WebhookRequestActionMissing => {
write!(f, "Webhook request action is missing")
}
TenantConfigError::WrongStructure => write!(f, "Config is broken"),
TenantConfigError::ExtraConfigMissing => write!(f, "Extra config is missing"),
TenantConfigError::ExtraConfigExpoTokenMissing => {
write!(f, "Extra config expo token is missing")
}
TenantConfigError::ExtraConfigPushSettingsMissing => {
write!(f, "Extra push config expo token is missing")
}
}
}
}
impl Error for TenantConfigError {}
pub type TenantConfigResult = Result<Config, TenantConfigError>;
pub type TenantResult = Result<TenantConfig, TenantConfigError>;
impl TenantConfig {
pub fn new() -> Self {
Self::default()
}
pub fn insert(&mut self, key: String, value: Config) {
self.0.insert(key, value);
}
pub fn get(&self, key: &str) -> TenantConfigResult {
if let Some(value) = self.0.get(key) {
let res = value.clone();
return Ok(res);
}
Err(TenantConfigError::Missing)
}
pub fn keys(&self) -> std::collections::hash_map::Keys<'_, std::string::String, Config> {
self.0.keys()
}
}