#[cfg(feature = "serde_json")]
pub(crate) use serde_impl::data_to_value;
#[cfg(feature = "serde_json")]
pub(crate) use serde_impl::value_to_data;
#[cfg(feature = "serde_json")]
mod serde_impl {
use super::super::DataValue;
use bumpalo::Bump;
use serde_json::Value;
pub(crate) fn data_to_value(v: &DataValue<'_>) -> Value {
match v {
#[cfg(feature = "datetime")]
DataValue::DateTime(dt) => {
crate::serde_bridge::datetime_sentinel("datetime", dt.to_iso_string())
}
#[cfg(feature = "datetime")]
DataValue::Duration(d) => {
crate::serde_bridge::datetime_sentinel("timestamp", d.to_string())
}
DataValue::Array(items) => Value::Array(items.iter().map(data_to_value).collect()),
DataValue::Object(pairs) => {
let mut map = serde_json::Map::with_capacity(pairs.len());
for (k, v) in *pairs {
map.insert((*k).to_string(), data_to_value(v));
}
Value::Object(map)
}
other => other.to_serde_value(),
}
}
pub(crate) fn value_to_data<'a>(v: &'a Value, arena: &'a Bump) -> DataValue<'a> {
match v {
Value::Null => DataValue::Null,
Value::Bool(b) => DataValue::Bool(*b),
Value::Number(n) => DataValue::Number(number(n)),
Value::String(s) => DataValue::String(s.as_str()),
Value::Array(items) => DataValue::Array(
arena.alloc_slice_fill_iter(items.iter().map(|item| value_to_data(item, arena))),
),
Value::Object(map) => DataValue::Object(
arena.alloc_slice_fill_iter(
map.iter()
.map(|(k, item)| (k.as_str(), value_to_data(item, arena))),
),
),
}
}
fn number(n: &serde_json::Number) -> datavalue::NumberValue {
use datavalue::NumberValue;
if let Some(i) = n.as_i64() {
NumberValue::Integer(i)
} else if let Some(u) = n.as_u64() {
NumberValue::from_u64(u)
} else {
NumberValue::Float(n.as_f64().unwrap_or(0.0))
}
}
}