use serde::{Deserialize, Serialize};
pub type ValueRef = u32;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum Value {
Null,
Bool {
value: bool,
},
Int {
value: i64,
},
Float {
value: f64,
},
String {
value: String,
},
List {
items: Vec<ValueRef>,
},
Object {
fields: Vec<(String, ValueRef)>,
},
}
impl Value {
pub fn s(s: impl Into<String>) -> Self {
Value::String { value: s.into() }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn json_roundtrip_scalars() {
for v in [
Value::Null,
Value::Bool { value: true },
Value::Int { value: 42 },
Value::Float { value: 1.5 },
Value::s("hello"),
] {
let s = serde_json::to_string(&v).unwrap();
let back: Value = serde_json::from_str(&s).unwrap();
assert_eq!(v, back);
}
}
#[test]
fn json_roundtrip_compound() {
let list = Value::List {
items: vec![0, 1, 2],
};
let obj = Value::Object {
fields: vec![("a".into(), 0), ("b".into(), 1)],
};
for v in [list, obj] {
let s = serde_json::to_string(&v).unwrap();
let back: Value = serde_json::from_str(&s).unwrap();
assert_eq!(v, back);
}
}
}