notifica-common 0.2.0

Notifica sdk
Documentation
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()
    }
}