use alloc::{boxed::Box, format, string::String, vec::Vec};
use core::iter::Peekable;
use serde::de::{self, Deserializer as _};
use super::{Error, Integer, Value};
use crate::core::tag;
use crate::tag::TagAccess;
impl From<Integer> for de::Unexpected<'_> {
#[inline]
fn from(value: Integer) -> Self {
u64::try_from(value)
.map(de::Unexpected::Unsigned)
.unwrap_or_else(|_| {
i64::try_from(value)
.map(de::Unexpected::Signed)
.unwrap_or(de::Unexpected::Other("large integer"))
})
}
}
impl<'a> From<&'a Value> for de::Unexpected<'a> {
#[inline]
fn from(value: &'a Value) -> Self {
match value {
Value::Bool(x) => Self::Bool(*x),
Value::Integer(x) => Self::from(*x),
Value::Float(x) => Self::Float(*x),
Value::Bytes(x) => Self::Bytes(x),
Value::Text(x) => Self::Str(x),
Value::Array(..) => Self::Seq,
Value::Map(..) => Self::Map,
Value::Null => Self::Other("null"),
Value::Tag(..) => Self::Other("tag"),
}
}
}
macro_rules! mkvisit {
($($f:ident($v:ty)),+ $(,)?) => {
$(
#[inline]
fn $f<E: de::Error>(self, v: $v) -> Result<Self::Value, E> {
Ok(v.into())
}
)+
};
}
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = Value;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "a valid CBOR item")
}
mkvisit! {
visit_bool(bool),
visit_f32(f32),
visit_f64(f64),
visit_i8(i8),
visit_i16(i16),
visit_i32(i32),
visit_i64(i64),
visit_i128(i128),
visit_u8(u8),
visit_u16(u16),
visit_u32(u32),
visit_u64(u64),
visit_u128(u128),
visit_char(char),
visit_str(&str),
visit_borrowed_str(&'de str),
visit_string(String),
visit_bytes(&[u8]),
visit_borrowed_bytes(&'de [u8]),
visit_byte_buf(Vec<u8>),
}
#[inline]
fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
Ok(Value::Null)
}
#[inline]
fn visit_some<D: de::Deserializer<'de>>(
self,
deserializer: D,
) -> Result<Self::Value, D::Error> {
deserializer.deserialize_any(self)
}
#[inline]
fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
Ok(Value::Null)
}
#[inline]
fn visit_newtype_struct<D: de::Deserializer<'de>>(
self,
deserializer: D,
) -> Result<Self::Value, D::Error> {
deserializer.deserialize_any(self)
}
#[inline]
fn visit_seq<A: de::SeqAccess<'de>>(self, mut acc: A) -> Result<Self::Value, A::Error> {
let mut seq = Vec::new();
while let Some(elem) = acc.next_element()? {
seq.push(elem);
}
Ok(Value::Array(seq))
}
#[inline]
fn visit_map<A: de::MapAccess<'de>>(self, mut acc: A) -> Result<Self::Value, A::Error> {
let mut map = Vec::<(Value, Value)>::with_capacity(
acc.size_hint().filter(|&l| l < 1024).unwrap_or(0),
);
while let Some(kv) = acc.next_entry()? {
map.push(kv);
}
Ok(Value::Map(map))
}
#[inline]
fn visit_enum<A: de::EnumAccess<'de>>(self, acc: A) -> Result<Self::Value, A::Error> {
use de::VariantAccess;
struct Inner;
impl<'de> de::Visitor<'de> for Inner {
type Value = Value;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "a tag number and a value")
}
#[inline]
fn visit_seq<A: de::SeqAccess<'de>>(self, mut acc: A) -> Result<Self::Value, A::Error> {
let tag: u64 = acc
.next_element()?
.ok_or_else(|| de::Error::custom("expected tag"))?;
let val = acc
.next_element()?
.ok_or_else(|| de::Error::custom("expected value"))?;
Ok(Value::Tag(tag, Box::new(val)))
}
}
let (name, data): (String, _) = acc.variant()?;
if name != crate::tag::TAGGED {
return Err(de::Error::custom("expected tag"));
}
data.tuple_variant(2, Inner)
}
}
impl<'de> de::Deserialize<'de> for Value {
#[inline]
fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_any(Visitor)
}
}
struct Deserializer<T>(T);
impl Deserializer<&Value> {
fn integer<N>(&self, kind: &'static str) -> Result<N, Error>
where
N: TryFrom<u128> + TryFrom<i128>,
{
fn raw(value: &Value) -> Result<u128, Error> {
let mut buffer = [0u8; 16];
let bytes = match value {
Value::Bytes(bytes) => {
let mut bytes: &[u8] = bytes.as_ref();
while bytes.len() > buffer.len() && bytes[0] == 0 {
bytes = &bytes[1..];
}
if bytes.len() > buffer.len() {
return Err(de::Error::custom("bigint too large"));
}
bytes
}
_ => return Err(de::Error::invalid_type(value.into(), &"bytes")),
};
buffer[16 - bytes.len()..].copy_from_slice(bytes);
Ok(u128::from_be_bytes(buffer))
}
let err = || de::Error::invalid_type(self.0.into(), &kind);
Ok(match self.0 {
Value::Integer(x) => i128::from(*x).try_into().map_err(|_| err())?,
Value::Tag(t, v) if *t == tag::BIGPOS => raw(v)?.try_into().map_err(|_| err())?,
Value::Tag(t, v) if *t == tag::BIGNEG => i128::try_from(raw(v)?)
.map(|x| x ^ !0)
.map_err(|_| err())
.and_then(|x| x.try_into().map_err(|_| err()))?,
_ => return Err(de::Error::invalid_type(self.0.into(), &"(big)int")),
})
}
}
impl<'de> de::Deserializer<'de> for Deserializer<&Value> {
type Error = Error;
#[inline]
fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
match self.0 {
Value::Bytes(x) => visitor.visit_bytes(x),
Value::Text(x) => visitor.visit_str(x),
Value::Array(x) => visitor.visit_seq(Deserializer(x.iter())),
Value::Map(x) => visitor.visit_map(Deserializer(x.iter().peekable())),
Value::Bool(x) => visitor.visit_bool(*x),
Value::Null => visitor.visit_none(),
Value::Tag(t, v) => {
let parent: Deserializer<&Value> = Deserializer(v);
visitor.visit_enum(TagAccess::new(parent, Some(*t)))
}
Value::Integer(x) => {
if let Ok(x) = u64::try_from(*x) {
visitor.visit_u64(x)
} else if let Ok(x) = i64::try_from(*x) {
visitor.visit_i64(x)
} else {
visitor.visit_i128(i128::from(*x))
}
}
Value::Float(x) => visitor.visit_f64(*x),
}
}
#[inline]
fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
let mut value = self.0;
while let Value::Tag(.., v) = value {
value = v;
}
match value {
Value::Bool(x) => visitor.visit_bool(*x),
_ => Err(de::Error::invalid_type(value.into(), &"bool")),
}
}
#[inline]
fn deserialize_f32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
self.deserialize_f64(visitor)
}
#[inline]
fn deserialize_f64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
let mut value = self.0;
while let Value::Tag(.., v) = value {
value = v;
}
match value {
Value::Float(x) => visitor.visit_f64(*x),
_ => Err(de::Error::invalid_type(value.into(), &"f64")),
}
}
fn deserialize_i8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_i8(self.integer("i8")?)
}
fn deserialize_i16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_i16(self.integer("i16")?)
}
fn deserialize_i32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_i32(self.integer("i32")?)
}
fn deserialize_i64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_i64(self.integer("i64")?)
}
fn deserialize_i128<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_i128(self.integer("i128")?)
}
fn deserialize_u8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_u8(self.integer("u8")?)
}
fn deserialize_u16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_u16(self.integer("u16")?)
}
fn deserialize_u32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_u32(self.integer("u32")?)
}
fn deserialize_u64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_u64(self.integer("u64")?)
}
fn deserialize_u128<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_u128(self.integer("u128")?)
}
fn deserialize_char<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
let mut value = self.0;
while let Value::Tag(.., v) = value {
value = v;
}
if let Value::Text(x) = value {
let mut chars = x.chars();
if let (Some(c), None) = (chars.next(), chars.next()) {
return visitor.visit_char(c);
}
}
Err(de::Error::invalid_type(value.into(), &"char"))
}
fn deserialize_str<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
let mut value = self.0;
while let Value::Tag(.., v) = value {
value = v;
}
match value {
Value::Text(x) => visitor.visit_str(x),
_ => Err(de::Error::invalid_type(value.into(), &"str")),
}
}
fn deserialize_string<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
self.deserialize_str(visitor)
}
fn deserialize_bytes<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
let mut value = self.0;
while let Value::Tag(.., v) = value {
value = v;
}
match value {
Value::Bytes(x) => visitor.visit_bytes(x),
Value::Array(x) => visitor.visit_seq(Deserializer(x.iter())),
_ => Err(de::Error::invalid_type(value.into(), &"bytes")),
}
}
fn deserialize_byte_buf<V: de::Visitor<'de>>(
self,
visitor: V,
) -> Result<V::Value, Self::Error> {
self.deserialize_bytes(visitor)
}
fn deserialize_seq<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
let mut value = self.0;
while let Value::Tag(.., v) = value {
value = v;
}
match value {
Value::Array(x) => visitor.visit_seq(Deserializer(x.iter())),
_ => Err(de::Error::invalid_type(value.into(), &"array")),
}
}
fn deserialize_map<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
let mut value = self.0;
while let Value::Tag(.., v) = value {
value = v;
}
match value {
Value::Map(x) => visitor.visit_map(Deserializer(x.iter().peekable())),
_ => Err(de::Error::invalid_type(value.into(), &"map")),
}
}
fn deserialize_struct<V: de::Visitor<'de>>(
self,
name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error> {
let Some(marker) = crate::ser::parse_struct_marker(name) else {
return self.deserialize_map(visitor);
};
let mut value = self.0;
if let Some(tag) = marker.tag {
let mut seen = false;
while let Value::Tag(t, v) = value {
seen |= *t == tag;
value = v;
}
if !seen {
return Err(de::Error::custom(format!("expected tag({tag})")));
}
} else {
while let Value::Tag(.., v) = value {
value = v;
}
}
match value {
Value::Map(x) => visitor.visit_map(StructAccess {
iter: x.iter().peekable(),
keys: marker.keys,
}),
_ => Err(de::Error::invalid_type(value.into(), &"map")),
}
}
fn deserialize_tuple<V: de::Visitor<'de>>(
self,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error> {
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V: de::Visitor<'de>>(
self,
name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error> {
match unwrap_struct_tag(name, self.0)? {
Some(value) => Deserializer(value).deserialize_seq(visitor),
None => self.deserialize_seq(visitor),
}
}
fn deserialize_identifier<V: de::Visitor<'de>>(
self,
visitor: V,
) -> Result<V::Value, Self::Error> {
let mut value = self.0;
while let Value::Tag(.., v) = value {
value = v;
}
match value {
Value::Text(x) => visitor.visit_str(x),
Value::Integer(x) => visitor.visit_str(&format!(
"{}{}",
crate::de::INT_KEY_PLACEHOLDER,
i128::from(*x)
)),
_ => Err(de::Error::invalid_type(value.into(), &"str or integer")),
}
}
fn deserialize_ignored_any<V: de::Visitor<'de>>(
self,
visitor: V,
) -> Result<V::Value, Self::Error> {
self.deserialize_any(visitor)
}
#[inline]
fn deserialize_option<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
match self.0 {
Value::Null => visitor.visit_none(),
x => visitor.visit_some(Self(x)),
}
}
#[inline]
fn deserialize_unit<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
match self.0 {
Value::Null => visitor.visit_unit(),
_ => Err(de::Error::invalid_type(self.0.into(), &"null")),
}
}
#[inline]
fn deserialize_unit_struct<V: de::Visitor<'de>>(
self,
name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error> {
match unwrap_struct_tag(name, self.0)? {
Some(value) => Deserializer(value).deserialize_unit(visitor),
None => self.deserialize_unit(visitor),
}
}
#[inline]
fn deserialize_newtype_struct<V: de::Visitor<'de>>(
self,
name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error> {
if name == crate::raw::NAME {
let bytes = crate::to_vec(self.0).map_err(de::Error::custom)?;
return visitor.visit_byte_buf(bytes);
}
match unwrap_struct_tag(name, self.0)? {
Some(value) => visitor.visit_newtype_struct(Deserializer(value)),
None => visitor.visit_newtype_struct(self),
}
}
#[inline]
fn deserialize_enum<V: de::Visitor<'de>>(
self,
name: &'static str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error> {
if name == crate::tag::NAME {
let (tag, val) = match self.0 {
Value::Tag(t, v) => (Some(*t), v.as_ref()),
v => (None, v),
};
let parent: Deserializer<&Value> = Deserializer(val);
return visitor.visit_enum(TagAccess::new(parent, tag));
}
match self.0 {
Value::Tag(.., v) => Deserializer(v.as_ref()).deserialize_enum(name, variants, visitor),
Value::Map(x) if x.len() == 1 => visitor.visit_enum(KeyedEnum {
pair: &x[0],
keys: crate::ser::parse_struct_marker(name).map_or("", |marker| marker.keys),
}),
x @ Value::Text(..) => visitor.visit_enum(Deserializer(x)),
_ => Err(de::Error::invalid_type(self.0.into(), &"map")),
}
}
#[inline]
fn is_human_readable(&self) -> bool {
false
}
}
impl<'a, 'de, T: Iterator<Item = &'a Value>> de::SeqAccess<'de> for Deserializer<T> {
type Error = Error;
#[inline]
fn next_element_seed<U: de::DeserializeSeed<'de>>(
&mut self,
seed: U,
) -> Result<Option<U::Value>, Self::Error> {
match self.0.next() {
None => Ok(None),
Some(v) => seed.deserialize(Deserializer(v)).map(Some),
}
}
}
impl<'a, 'de, T: Iterator<Item = &'a (Value, Value)>> de::MapAccess<'de>
for Deserializer<Peekable<T>>
{
type Error = Error;
#[inline]
fn next_key_seed<K: de::DeserializeSeed<'de>>(
&mut self,
seed: K,
) -> Result<Option<K::Value>, Self::Error> {
match self.0.peek() {
None => Ok(None),
Some(x) => Ok(Some(seed.deserialize(Deserializer(&x.0))?)),
}
}
#[inline]
fn next_value_seed<V: de::DeserializeSeed<'de>>(
&mut self,
seed: V,
) -> Result<V::Value, Self::Error> {
seed.deserialize(Deserializer(&self.0.next().unwrap().1))
}
#[inline]
fn next_entry_seed<K: de::DeserializeSeed<'de>, V: de::DeserializeSeed<'de>>(
&mut self,
kseed: K,
vseed: V,
) -> Result<Option<(K::Value, V::Value)>, Self::Error> {
match self.0.next() {
Some((k, v)) => Ok(Some((
kseed.deserialize(Deserializer(k))?,
vseed.deserialize(Deserializer(v))?,
))),
None => Ok(None),
}
}
#[inline]
fn size_hint(&self) -> Option<usize> {
match self.0.size_hint() {
(lower, Some(upper)) if lower == upper => Some(upper),
_ => None,
}
}
}
fn unwrap_struct_tag<'x>(
name: &'static str,
mut value: &'x Value,
) -> Result<Option<&'x Value>, Error> {
let Some(crate::ser::StructMarker { tag: Some(tag), .. }) =
crate::ser::parse_struct_marker(name)
else {
return Ok(None);
};
let mut seen = false;
while let Value::Tag(t, v) = value {
seen |= *t == tag;
value = v;
}
match seen {
true => Ok(Some(value)),
false => Err(de::Error::custom(format!("expected tag({tag})"))),
}
}
struct StructAccess<'a, T: Iterator<Item = &'a (Value, Value)>> {
iter: Peekable<T>,
keys: &'static str,
}
impl<'a, 'de, T: Iterator<Item = &'a (Value, Value)>> de::MapAccess<'de> for StructAccess<'a, T> {
type Error = Error;
fn next_key_seed<K: de::DeserializeSeed<'de>>(
&mut self,
seed: K,
) -> Result<Option<K::Value>, Self::Error> {
let Some(pair) = self.iter.peek() else {
return Ok(None);
};
let pair: &'a (Value, Value) = pair;
let mut key = &pair.0;
while let Value::Tag(.., v) = key {
key = v;
}
let Value::Integer(x) = key else {
return seed.deserialize(Deserializer(&pair.0)).map(Some);
};
let key = i128::from(*x);
match crate::ser::field_for_key(self.keys, key) {
Some(field) => seed
.deserialize(de::value::StrDeserializer::new(field))
.map(Some),
None => seed
.deserialize(de::value::StringDeserializer::new(format!(
"{}{key}",
crate::de::INT_KEY_PLACEHOLDER
)))
.map(Some),
}
}
#[inline]
fn next_value_seed<V: de::DeserializeSeed<'de>>(
&mut self,
seed: V,
) -> Result<V::Value, Self::Error> {
seed.deserialize(Deserializer(&self.iter.next().expect("peeked").1))
}
#[inline]
fn size_hint(&self) -> Option<usize> {
match self.iter.size_hint() {
(lower, Some(upper)) if lower == upper => Some(upper),
_ => None,
}
}
}
struct KeyedEnum<'a> {
pair: &'a (Value, Value),
keys: &'static str,
}
impl<'a, 'de> de::EnumAccess<'de> for KeyedEnum<'a> {
type Error = Error;
type Variant = KeyedVariant<'a>;
#[inline]
fn variant_seed<V: de::DeserializeSeed<'de>>(
self,
seed: V,
) -> Result<(V::Value, Self::Variant), Self::Error> {
let key = seed.deserialize(Deserializer(&self.pair.0))?;
Ok((
key,
KeyedVariant {
value: &self.pair.1,
keys: self.keys,
},
))
}
}
struct KeyedVariant<'a> {
value: &'a Value,
keys: &'static str,
}
impl<'de> de::VariantAccess<'de> for KeyedVariant<'_> {
type Error = Error;
#[inline]
fn unit_variant(self) -> Result<(), Self::Error> {
de::VariantAccess::unit_variant(Deserializer(self.value))
}
#[inline]
fn newtype_variant_seed<U: de::DeserializeSeed<'de>>(
self,
seed: U,
) -> Result<U::Value, Self::Error> {
seed.deserialize(Deserializer(self.value))
}
#[inline]
fn tuple_variant<V: de::Visitor<'de>>(
self,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error> {
Deserializer(self.value).deserialize_seq(visitor)
}
#[inline]
fn struct_variant<V: de::Visitor<'de>>(
self,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error> {
let mut value = self.value;
while let Value::Tag(.., v) = value {
value = v;
}
match value {
Value::Map(x) => visitor.visit_map(StructAccess {
iter: x.iter().peekable(),
keys: self.keys,
}),
_ => Err(de::Error::invalid_type(value.into(), &"map")),
}
}
}
impl<'a, 'de> de::EnumAccess<'de> for Deserializer<&'a Value> {
type Error = Error;
type Variant = Deserializer<&'a Value>;
#[inline]
fn variant_seed<V: de::DeserializeSeed<'de>>(
self,
seed: V,
) -> Result<(V::Value, Self::Variant), Self::Error> {
let key = seed.deserialize(self)?;
Ok((key, Deserializer(&Value::Null)))
}
}
impl<'de> de::VariantAccess<'de> for Deserializer<&Value> {
type Error = Error;
#[inline]
fn unit_variant(self) -> Result<(), Self::Error> {
match self.0 {
Value::Null => Ok(()),
_ => Err(de::Error::invalid_type(self.0.into(), &"unit")),
}
}
#[inline]
fn newtype_variant_seed<U: de::DeserializeSeed<'de>>(
self,
seed: U,
) -> Result<U::Value, Self::Error> {
seed.deserialize(self)
}
#[inline]
fn tuple_variant<V: de::Visitor<'de>>(
self,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error> {
self.deserialize_seq(visitor)
}
#[inline]
fn struct_variant<V: de::Visitor<'de>>(
self,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error> {
self.deserialize_map(visitor)
}
}
impl Value {
#[inline]
pub fn deserialized<'de, T: de::Deserialize<'de>>(&self) -> Result<T, Error> {
T::deserialize(Deserializer(self))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn size_hint_follows_the_iterator() {
let pairs = [(Value::Null, Value::Null), (Value::Null, Value::Null)];
let exact = Deserializer(pairs.iter().peekable());
assert_eq!(de::MapAccess::size_hint(&exact), Some(2));
let inexact = Deserializer(pairs.iter().filter(|_| true).peekable());
assert_eq!(de::MapAccess::size_hint(&inexact), None);
}
}