safeapp-notifier 0.5.7

Safe App Notifications Service
Documentation
use serde::{
    Deserialize, Deserializer, Serialize, Serializer,
    de::{self, Visitor},
};
use std::fmt;

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EventKey {
    Account(AccountEventKey),
    Sync(SyncEventKey),
}

impl EventKey {
    pub fn as_str(&self) -> &'static str {
        match self {
            EventKey::Account(key) => key.as_str(),
            EventKey::Sync(key) => key.as_str(),
        }
    }

    pub fn to_subject(&self) -> String {
        match self {
            EventKey::Account(account_key) => match account_key {
                AccountEventKey::Welcome => "Welcome to Safe App".to_string(),
                AccountEventKey::TierUpgrade => "Your Account Tier Has Been Upgraded".to_string(),
            },
            EventKey::Sync(sync_key) => match sync_key {
                SyncEventKey::Connection(connection_key) => match connection_key {
                    ConnectionEventKey::Finished => "Connection Syncing Completed".to_string(),
                    ConnectionEventKey::Added => "New Connection Added".to_string(),
                },
                SyncEventKey::Disputer(disputer_key) => match disputer_key {
                    DisputerEventKey::PendingCharges(pending_key) => match pending_key {
                        PendingChargeEventKey::Payment => "Pending Charge Payment Processed".to_string(),
                        PendingChargeEventKey::LimitReached => "Pending Charges Limit Reached".to_string(),
                        PendingChargeEventKey::Added => "New Pending Charge Added".to_string(),
                    },
                    DisputerEventKey::Disputes(dispute_key) => match dispute_key {
                        DisputeEventKey::Created => "New Dispute Created".to_string(),
                        DisputeEventKey::Won => "Dispute Won".to_string(),
                        DisputeEventKey::Lost => "Dispute Lost".to_string(),
                    },
                    DisputerEventKey::Evidences(evidence_key) => match evidence_key {
                        EvidencesEventKey::Submitted => "Evidence Submitted for Dispute".to_string(),
                    },
                },
            },
        }
    }
}

// Custom serialization (unchanged)
impl Serialize for EventKey {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

// Custom deserialization with fallback for unknown keys
impl<'de> Deserialize<'de> for EventKey {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct EventKeyVisitor;

        impl<'de> Visitor<'de> for EventKeyVisitor {
            type Value = EventKey;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("a valid event key string")
            }

            fn visit_str<E>(self, value: &str) -> Result<EventKey, E>
            where
                E: de::Error,
            {
                match value {
                    "account.welcome" => Ok(keys::ACCOUNT_WELCOME),
                    "account.tier_upgrade" => Ok(keys::ACCOUNT_TIER_UPGRADE),
                    "sync.connection.finished" => Ok(keys::SYNC_CONNECTION_FINISHED),
                    "sync.connection.added" => Ok(keys::SYNC_CONNECTION_ADDED),
                    "sync.disputer.pending_charges.payment" => Ok(keys::SYNC_DISPUTER_PENDING_CHARGES_PAYMENT),
                    "sync.disputer.pending_charges.limit_reached" => {
                        Ok(keys::SYNC_DISPUTER_PENDING_CHARGES_LIMIT_REACHED)
                    }
                    "sync.disputer.pending_charges.added" => Ok(keys::SYNC_DISPUTER_PENDING_CHARGES_ADDED),
                    "sync.disputer.disputes.created" => Ok(keys::SYNC_DISPUTER_DISPUTES_CREATED),
                    "sync.disputer.disputes.won" => Ok(keys::SYNC_DISPUTER_DISPUTES_WON),
                    "sync.disputer.disputes.lost" => Ok(keys::SYNC_DISPUTER_DISPUTES_LOST),
                    "sync.disputer.evidences.submitted" => Ok(keys::SYNC_DISPUTER_EVIDENCES_SUBMITTED),
                    unknown => {
                        // Optionally log unknown keys for debugging
                        eprintln!("Unknown event key '{}', expected a known key", unknown);
                        Err(de::Error::custom(format!("Unknown event key: {}", unknown)))
                    }
                }
            }
        }

        deserializer.deserialize_str(EventKeyVisitor)
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum AccountEventKey {
    Welcome,
    TierUpgrade,
}

impl AccountEventKey {
    pub fn as_str(&self) -> &'static str {
        match self {
            AccountEventKey::Welcome => "account.welcome",
            AccountEventKey::TierUpgrade => "account.tier_upgrade",
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum SyncEventKey {
    Connection(ConnectionEventKey),
    Disputer(DisputerEventKey),
}

impl SyncEventKey {
    pub fn as_str(&self) -> &'static str {
        match self {
            SyncEventKey::Connection(key) => key.as_str(),
            SyncEventKey::Disputer(key) => key.as_str(),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ConnectionEventKey {
    Finished,
    Added,
}

impl ConnectionEventKey {
    pub fn as_str(&self) -> &'static str {
        match self {
            ConnectionEventKey::Finished => "sync.connection.finished",
            ConnectionEventKey::Added => "sync.connection.added",
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum DisputerEventKey {
    PendingCharges(PendingChargeEventKey),
    Disputes(DisputeEventKey),
    Evidences(EvidencesEventKey),
}

impl DisputerEventKey {
    pub fn as_str(&self) -> &'static str {
        match self {
            DisputerEventKey::PendingCharges(key) => key.as_str(),
            DisputerEventKey::Disputes(key) => key.as_str(),
            DisputerEventKey::Evidences(key) => key.as_str(),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum DisputeEventKey {
    Created,
    Won,
    Lost,
}

impl DisputeEventKey {
    pub fn as_str(&self) -> &'static str {
        match self {
            DisputeEventKey::Created => "sync.disputer.disputes.created",
            DisputeEventKey::Won => "sync.disputer.disputes.won",
            DisputeEventKey::Lost => "sync.disputer.disputes.lost",
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum PendingChargeEventKey {
    Payment,
    LimitReached,
    Added,
}

impl PendingChargeEventKey {
    pub fn as_str(&self) -> &'static str {
        match self {
            PendingChargeEventKey::Payment => "sync.disputer.pending_charges.payment",
            PendingChargeEventKey::LimitReached => "sync.disputer.pending_charges.limit_reached",
            PendingChargeEventKey::Added => "sync.disputer.pending_charges.added",
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum EvidencesEventKey {
    Submitted,
}

impl EvidencesEventKey {
    pub fn as_str(&self) -> &'static str {
        match self {
            EvidencesEventKey::Submitted => "sync.disputer.evidences.submitted",
        }
    }
}

pub mod keys {
    use super::*;

    pub const ACCOUNT_WELCOME: EventKey = EventKey::Account(AccountEventKey::Welcome);
    pub const ACCOUNT_TIER_UPGRADE: EventKey = EventKey::Account(AccountEventKey::TierUpgrade);

    pub const SYNC_CONNECTION_FINISHED: EventKey =
        EventKey::Sync(SyncEventKey::Connection(ConnectionEventKey::Finished));
    pub const SYNC_CONNECTION_ADDED: EventKey = EventKey::Sync(SyncEventKey::Connection(ConnectionEventKey::Added));

    pub const SYNC_DISPUTER_PENDING_CHARGES_PAYMENT: EventKey = EventKey::Sync(SyncEventKey::Disputer(
        DisputerEventKey::PendingCharges(PendingChargeEventKey::Payment),
    ));
    pub const SYNC_DISPUTER_PENDING_CHARGES_LIMIT_REACHED: EventKey = EventKey::Sync(SyncEventKey::Disputer(
        DisputerEventKey::PendingCharges(PendingChargeEventKey::LimitReached),
    ));
    pub const SYNC_DISPUTER_PENDING_CHARGES_ADDED: EventKey = EventKey::Sync(SyncEventKey::Disputer(
        DisputerEventKey::PendingCharges(PendingChargeEventKey::Added),
    ));
    pub const SYNC_DISPUTER_DISPUTES_CREATED: EventKey = EventKey::Sync(SyncEventKey::Disputer(
        DisputerEventKey::Disputes(DisputeEventKey::Created),
    ));
    pub const SYNC_DISPUTER_DISPUTES_WON: EventKey =
        EventKey::Sync(SyncEventKey::Disputer(DisputerEventKey::Disputes(DisputeEventKey::Won)));
    pub const SYNC_DISPUTER_DISPUTES_LOST: EventKey = EventKey::Sync(SyncEventKey::Disputer(
        DisputerEventKey::Disputes(DisputeEventKey::Lost),
    ));
    pub const SYNC_DISPUTER_EVIDENCES_SUBMITTED: EventKey = EventKey::Sync(SyncEventKey::Disputer(
        DisputerEventKey::Evidences(EvidencesEventKey::Submitted),
    ));
}