use tabnas::Value;
pub fn to_json(value: &Value) -> serde_json::Value {
match value {
Value::Null => serde_json::Value::Null,
Value::Bool(b) => serde_json::Value::Bool(*b),
Value::Number(n) => serde_json::Number::from_f64(*n)
.map(serde_json::Value::Number)
.unwrap_or(serde_json::Value::Null),
Value::String(s) => serde_json::Value::String(s.clone()),
Value::Array(items) => serde_json::Value::Array(items.iter().map(to_json).collect()),
Value::Object(entries) => serde_json::Value::Object(
entries
.iter()
.map(|(k, v)| (k.clone(), to_json(v)))
.collect(),
),
other => serde_json::Value::String(format!("<unrepresentable: {other:?}>")),
}
}
pub fn same(a: &serde_json::Value, b: &serde_json::Value) -> bool {
use serde_json::Value as J;
match (a, b) {
(J::Number(x), J::Number(y)) => match (x.as_f64(), y.as_f64()) {
(Some(x), Some(y)) => x.to_bits() == y.to_bits(),
_ => x == y,
},
(J::Array(x), J::Array(y)) => {
x.len() == y.len() && x.iter().zip(y).all(|(x, y)| same(x, y))
}
(J::Object(x), J::Object(y)) => {
x.len() == y.len()
&& x.iter()
.zip(y)
.all(|((xk, xv), (yk, yv))| xk == yk && same(xv, yv))
}
_ => a == b,
}
}