shakemyleg 3.0.0

A simple state machine definition language and interpreter.
Documentation
use json::JsonValue;

use crate::error::{SML_Result, SML_Error};


#[derive(Debug, Clone)]
pub enum Value {
    String(String),
    Number(f64),
    Bool(bool),
    List(Vec<Box<Value>>),
}

impl Value {
    pub fn new(json: &JsonValue) -> SML_Result<Self> {
        if json.is_string() {
            let s = json.as_str().unwrap().to_string();
            Ok(Self::String(s))
        }
        else if json.is_number() {
            Ok(Self::Number(json.as_f64().unwrap()))
        }
        else if json.is_boolean() {
            Ok(Self::Bool(json.as_bool().unwrap()))
        }
        else if json.is_array() {
            let mut list = Vec::new();
            for item in json.members() {
                list.push(Box::new(Value::new(item)?));
            }
            Ok(Self::List(list))
        }
        else {
            Err(SML_Error::JsonFormatError("Value expects a json number, string, array, or boolean. Got null, object, or empty.".to_string()))
        }
    }

    pub fn as_bool(&self) -> bool {
        match self {
            Self::Bool(v) => *v,
            Self::Number(v) => *v != 0.0,
            Self::String(v) => !v.is_empty(),
            Self::List(v) => !v.is_empty(),
        }
    }

    pub fn as_json(&self) -> JsonValue {
        match &self {
            Self::Bool(b) => JsonValue::Boolean(*b),
            Self::String(s) => JsonValue::String(s.to_string()),
            Self::Number(n) => JsonValue::Number((*n).into()),
            Self::List(l) => {
                JsonValue::Array(l.iter().map(|v| v.as_json()).collect())
            }
        }
    }
}


impl PartialEq for Value {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (Self::String(s1), Self::String(s2)) => s1 == s2,
            (Self::Bool(b1), Self::Bool(b2)) => b1 == b2,
            (Self::Number(n1), Self::Number(n2)) => n1 == n2,
            (Self::List(l1), Self::List(l2)) => l1 == l2,
            _ => false
        }
    }
}