Skip to main content

native/kameleoon_elixir_bridge/src/variable_ex.rs

use kameleoon_core::types::{JsonValue, Variable};
use rustler::{Encoder, Env, Term};

use crate::utils_ex::ArcStr;

#[derive(Debug, rustler::NifStruct)]
#[module = "Kameleoon.Types.Variable"]
#[rustler(encode)]
pub(crate) struct VariableEx {
    key: ArcStr,
    kind: ArcStr,
    value: VariableValue,
}

impl From<Variable> for VariableEx {
    fn from(value: Variable) -> Self {
        Self {
            key: value.key.into(),
            kind: value.kind.into(),
            value: variable_value(value.value),
        }
    }
}

impl From<&Variable> for VariableEx {
    fn from(value: &Variable) -> Self {
        Self {
            key: value.key.clone().into(),
            kind: value.kind.clone().into(),
            value: variable_value(value.value.clone()),
        }
    }
}

#[derive(Debug)]
enum VariableValue {
    Boolean(bool),
    Number(f64),
    String(ArcStr),
}

impl Encoder for VariableValue {
    fn encode<'a>(&self, env: Env<'a>) -> Term<'a> {
        match self {
            Self::Boolean(value) => value.encode(env),
            Self::Number(value) => value.encode(env),
            Self::String(value) => value.encode(env),
        }
    }
}

fn variable_value(value: JsonValue) -> VariableValue {
    match value {
        JsonValue::Boolean(value) => VariableValue::Boolean(value),
        JsonValue::Number(value) => VariableValue::Number(value),
        JsonValue::String(value) | JsonValue::Json(value) | JsonValue::Js(value) | JsonValue::Css(value) => {
            VariableValue::String(ArcStr::from(value))
        }
    }
}