use miniserde::de::Visitor;
use miniserde::json::{Array, Number, Object, Value};
use miniserde::ser::Fragment;
use miniserde::{Deserialize, Error, Result, Serialize};
pub fn replay_value_to_visitor(value: &Value, visitor: &mut dyn Visitor) -> Result<()> {
match value {
Value::Null => visitor.null(),
Value::Bool(b) => visitor.boolean(*b),
Value::String(s) => visitor.string(s),
Value::Number(n) => match n {
Number::U64(n) => visitor.nonnegative(*n),
Number::I64(n) => visitor.negative(*n),
Number::F64(n) => visitor.float(*n),
},
Value::Array(arr) => {
let mut seq = visitor.seq()?;
for item in arr.iter() {
let element_visitor = seq.element()?;
replay_value_to_visitor(item, element_visitor)?;
}
seq.finish()
}
Value::Object(obj) => {
let mut map = visitor.map()?;
for (k, v) in obj.iter() {
let field_visitor = map.key(k)?;
replay_value_to_visitor(v, field_visitor)?;
}
map.finish()
}
}
}
pub fn from_value<T: Deserialize>(value: &Value) -> Result<T> {
let mut out: Option<T> = None;
let visitor = T::begin(&mut out);
replay_value_to_visitor(value, visitor)?;
out.ok_or(Error)
}
pub fn to_value<T: Serialize>(value: &T) -> Value {
fragment_to_value(value.begin())
}
fn fragment_to_value(fragment: Fragment<'_>) -> Value {
match fragment {
Fragment::Null => Value::Null,
Fragment::Bool(b) => Value::Bool(b),
Fragment::Str(s) => Value::String(s.into_owned()),
Fragment::U64(n) => Value::Number(Number::U64(n)),
Fragment::I64(n) => Value::Number(Number::I64(n)),
Fragment::F64(n) => Value::Number(Number::F64(n)),
Fragment::Seq(mut seq) => {
let mut arr = Array::new();
while let Some(elem) = seq.next() {
arr.push(fragment_to_value(elem.begin()));
}
Value::Array(arr)
}
Fragment::Map(mut map) => {
let mut obj = Object::new();
while let Some((k, v)) = map.next() {
obj.insert(k.into_owned(), fragment_to_value(v.begin()));
}
Value::Object(obj)
}
}
}