elfo-core 0.1.35

The core of the system
Documentation
use regex::Regex;
use serde::{
    de::{Deserializer, Error},
    Deserialize,
};

#[derive(Deserialize)]
#[serde(default)]
pub(crate) struct TelemetryConfig {
    pub(crate) per_actor_group: bool,
    pub(crate) per_actor_key: PerActorKey,
}

pub(crate) enum PerActorKey {
    Bool(bool),
    Replacement(Regex, String),
}

impl PerActorKey {
    pub(crate) fn is_enabled(&self) -> bool {
        match self {
            Self::Bool(flag) => *flag,
            Self::Replacement(_, _) => true,
        }
    }

    pub(crate) fn key(&self, actor_key: &str) -> Option<String> {
        match self {
            Self::Bool(_) => None,
            Self::Replacement(pattern, template) => {
                Some(pattern.replace(actor_key, template).into())
            }
        }
    }
}

impl<'de> Deserialize<'de> for PerActorKey {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Deserialize)]
        #[serde(untagged)]
        enum BoolOrPairOfStrings {
            Bool(bool),
            Pair(String, String),
        }

        Ok(match BoolOrPairOfStrings::deserialize(deserializer)? {
            BoolOrPairOfStrings::Bool(flag) => PerActorKey::Bool(flag),
            BoolOrPairOfStrings::Pair(pattern, template) => {
                let pattern = Regex::new(&pattern).map_err(D::Error::custom)?;
                PerActorKey::Replacement(pattern, template)
            }
        })
    }
}

impl Default for TelemetryConfig {
    fn default() -> Self {
        Self {
            per_actor_group: true,
            per_actor_key: PerActorKey::Bool(false),
        }
    }
}