use serde::de::{self, MapAccess, SeqAccess, Visitor};
use serde::{Deserialize, Deserializer};
use serde_json::Value;
use std::fmt;
pub(super) const LIMIT: usize = 1024 * 1024;
struct Strict(Value);
impl<'de> Deserialize<'de> for Strict {
fn deserialize<D: Deserializer<'de>>(d: D) -> std::result::Result<Self, D::Error> {
struct V;
impl<'de> Visitor<'de> for V {
type Value = Strict;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("bounded native JSON without duplicate keys")
}
fn visit_bool<E: de::Error>(self, v: bool) -> std::result::Result<Strict, E> {
Ok(Strict(v.into()))
}
fn visit_i64<E: de::Error>(self, v: i64) -> std::result::Result<Strict, E> {
Ok(Strict(v.into()))
}
fn visit_u64<E: de::Error>(self, v: u64) -> std::result::Result<Strict, E> {
Ok(Strict(v.into()))
}
fn visit_f64<E: de::Error>(self, v: f64) -> std::result::Result<Strict, E> {
serde_json::Number::from_f64(v)
.map(|n| Strict(Value::Number(n)))
.ok_or_else(|| de::Error::custom("nonfinite number"))
}
fn visit_str<E: de::Error>(self, v: &str) -> std::result::Result<Strict, E> {
Ok(Strict(v.into()))
}
fn visit_unit<E: de::Error>(self) -> std::result::Result<Strict, E> {
Ok(Strict(Value::Null))
}
fn visit_seq<A: SeqAccess<'de>>(
self,
mut a: A,
) -> std::result::Result<Strict, A::Error> {
let mut out = Vec::new();
while let Some(Strict(v)) = a.next_element()? {
out.push(v);
}
Ok(Strict(Value::Array(out)))
}
fn visit_map<A: MapAccess<'de>>(
self,
mut a: A,
) -> std::result::Result<Strict, A::Error> {
let mut out = serde_json::Map::new();
while let Some(k) = a.next_key::<String>()? {
if out.contains_key(&k) {
return Err(de::Error::custom("duplicate field"));
}
let Strict(v) = a.next_value()?;
out.insert(k, v);
}
Ok(Strict(Value::Object(out)))
}
}
d.deserialize_any(V)
}
}
pub(super) fn decode(bytes: &[u8]) -> Result<Value, &'static str> {
if bytes.is_empty() || bytes.len() > LIMIT {
return Err("native JSON size rejected");
}
let Strict(value) = serde_json::from_slice(bytes).map_err(|_| "native JSON rejected")?;
Ok(value)
}