use std::slice::Iter as ArrayIter;
use serde_json::Map;
use serde_json::Value;
use serde_json::map::Iter as ObjectIter;
pub(in crate::wire) enum CanonicalJsonFrame<'a> {
Array {
remaining: ArrayIter<'a, Value>,
output: Vec<Value>,
},
Object {
remaining: ObjectIter<'a>,
pending_key: Option<&'a str>,
output: Map<String, Value>,
},
}
impl<'a> CanonicalJsonFrame<'a> {
pub(in crate::wire) fn new(value: &'a Value) -> Option<Self> {
match value {
Value::Array(values) if !values.is_empty() => Some(Self::Array {
remaining: values.iter(),
output: Vec::with_capacity(values.len()),
}),
Value::Object(values) if !values.is_empty() => Some(Self::Object {
remaining: values.iter(),
pending_key: None,
output: Map::with_capacity(values.len()),
}),
_ => None,
}
}
pub(in crate::wire) fn next_child(&mut self) -> Option<&'a Value> {
match self {
Self::Array { remaining, .. } => remaining.next(),
Self::Object {
remaining,
pending_key,
..
} => {
debug_assert!(pending_key.is_none());
let (key, value) = remaining.next()?;
*pending_key = Some(key);
Some(value)
}
}
}
pub(in crate::wire) fn push(&mut self, child: Value) {
match self {
Self::Array { output, .. } => output.push(child),
Self::Object {
pending_key,
output,
..
} => {
let key = pending_key.take().expect("object child has a pending key");
output.insert(key.to_owned(), child);
}
}
}
pub(in crate::wire) fn finish(self) -> Value {
match self {
Self::Array { output, .. } => Value::Array(output),
Self::Object { mut output, .. } => {
output.sort_keys();
Value::Object(output)
}
}
}
}