// SPDX-License-Identifier: Apache-2.0 use super::{Error, Integer, Value}; use alloc::{boxed::Box, string::String, vec::Vec}; use core::iter::Peekable; use ciborium_ll::tag; use serde::de::{self, Deserializer as _}; impl<'a> From for de::Unexpected<'a> { #[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_else(|_| 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(self, v: $v) -> Result { Ok(v.into()) } )+ }; } struct Visitor; impl<'de> serde::de::Visitor<'de> for Visitor { type Value = Value; fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(formatter, "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), } #[inline] fn visit_none(self) -> Result { Ok(Value::Null) } #[inline] fn visit_some>( self, deserializer: D, ) -> Result { deserializer.deserialize_any(self) } #[inline] fn visit_unit(self) -> Result { Ok(Value::Null) } #[inline] fn visit_newtype_struct>( self, deserializer: D, ) -> Result { deserializer.deserialize_any(self) } #[inline] fn visit_seq>(self, mut acc: A) -> Result { let mut seq = Vec::new(); while let Some(elem) = acc.next_element()? { seq.push(elem); } Ok(Value::Array(seq)) } #[inline] fn visit_map>(self, mut acc: A) -> Result { let mut map = Vec::<(Value, Value)>::new(); while let Some(kv) = acc.next_entry()? { map.push(kv); } Ok(Value::Map(map)) } #[inline] fn visit_enum>(self, acc: A) -> Result { use serde::de::VariantAccess; struct Inner; impl<'de> serde::de::Visitor<'de> for Inner { type Value = Value; fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(formatter, "a valid CBOR item") } #[inline] fn visit_seq>(self, mut acc: A) -> Result { 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 val"))?; Ok(Value::Tag(tag, Box::new(val))) } } let (name, data): (String, _) = acc.variant()?; assert_eq!("@@TAGGED@@", name); data.tuple_variant(2, Inner) } } impl<'de> de::Deserialize<'de> for Value { #[inline] fn deserialize>(deserializer: D) -> Result { deserializer.deserialize_any(Visitor) } } struct Deserializer(T); impl<'a, 'de> Deserializer<&'a Value> { fn integer(&self, kind: &'static str) -> Result where N: TryFrom, N: TryFrom, { fn raw(value: &Value) -> Result { let mut buffer = 0u128.to_ne_bytes(); let length = buffer.len(); let bytes = match value { Value::Bytes(bytes) => { // Skip leading zeros... 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[length - 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<'a, 'de> de::Deserializer<'de> for Deserializer<&'a Value> { type Error = Error; #[inline] fn deserialize_any>(self, visitor: V) -> Result { 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); let access = crate::tag::TagAccess::new(parent, Some(*t)); visitor.visit_enum(access) } 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 if let Ok(x) = i128::try_from(*x) { visitor.visit_i128(x) } else { unreachable!() } } Value::Float(x) => visitor.visit_f64(*x), } } #[inline] fn deserialize_bool>(self, visitor: V) -> Result { 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>(self, visitor: V) -> Result { self.deserialize_f64(visitor) } #[inline] fn deserialize_f64>(self, visitor: V) -> Result { 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>(self, visitor: V) -> Result { visitor.visit_i8(self.integer("i8")?) } fn deserialize_i16>(self, visitor: V) -> Result { visitor.visit_i16(self.integer("i16")?) } fn deserialize_i32>(self, visitor: V) -> Result { visitor.visit_i32(self.integer("i32")?) } fn deserialize_i64>(self, visitor: V) -> Result { visitor.visit_i64(self.integer("i64")?) } fn deserialize_i128>(self, visitor: V) -> Result { visitor.visit_i128(self.integer("i128")?) } fn deserialize_u8>(self, visitor: V) -> Result { visitor.visit_u8(self.integer("u8")?) } fn deserialize_u16>(self, visitor: V) -> Result { visitor.visit_u16(self.integer("u16")?) } fn deserialize_u32>(self, visitor: V) -> Result { visitor.visit_u32(self.integer("u32")?) } fn deserialize_u64>(self, visitor: V) -> Result { visitor.visit_u64(self.integer("u64")?) } fn deserialize_u128>(self, visitor: V) -> Result { visitor.visit_u128(self.integer("u128")?) } fn deserialize_char>(self, visitor: V) -> Result { let mut value = self.0; while let Value::Tag(.., v) = value { value = v; } match value { Value::Text(x) => match x.chars().count() { 1 => visitor.visit_char(x.chars().next().unwrap()), _ => Err(de::Error::invalid_type(value.into(), &"char")), }, _ => Err(de::Error::invalid_type(value.into(), &"char")), } } fn deserialize_str>(self, visitor: V) -> Result { 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>(self, visitor: V) -> Result { self.deserialize_str(visitor) } fn deserialize_bytes>(self, visitor: V) -> Result { let mut value = self.0; while let Value::Tag(.., v) = value { value = v; } match value { Value::Bytes(x) => visitor.visit_bytes(x), _ => Err(de::Error::invalid_type(value.into(), &"bytes")), } } fn deserialize_byte_buf>( self, visitor: V, ) -> Result { self.deserialize_bytes(visitor) } fn deserialize_seq>(self, visitor: V) -> Result { 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>(self, visitor: V) -> Result { 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>( self, _name: &'static str, _fields: &'static [&'static str], visitor: V, ) -> Result { self.deserialize_map(visitor) } fn deserialize_tuple>( self, _len: usize, visitor: V, ) -> Result { self.deserialize_seq(visitor) } fn deserialize_tuple_struct>( self, _name: &'static str, _len: usize, visitor: V, ) -> Result { self.deserialize_seq(visitor) } fn deserialize_identifier>( self, visitor: V, ) -> Result { self.deserialize_str(visitor) } fn deserialize_ignored_any>( self, visitor: V, ) -> Result { self.deserialize_any(visitor) } #[inline] fn deserialize_option>(self, visitor: V) -> Result { match self.0 { Value::Null => visitor.visit_none(), x => visitor.visit_some(Self(x)), } } #[inline] fn deserialize_unit>(self, visitor: V) -> Result { match self.0 { Value::Null => visitor.visit_unit(), _ => Err(de::Error::invalid_type(self.0.into(), &"null")), } } #[inline] fn deserialize_unit_struct>( self, _name: &'static str, visitor: V, ) -> Result { self.deserialize_unit(visitor) } #[inline] fn deserialize_newtype_struct>( self, _name: &'static str, visitor: V, ) -> Result { visitor.visit_newtype_struct(self) } #[inline] fn deserialize_enum>( self, name: &'static str, variants: &'static [&'static str], visitor: V, ) -> Result { if name == "@@TAG@@" { let (tag, val) = match self.0 { Value::Tag(t, v) => (Some(*t), v.as_ref()), v => (None, v), }; let parent: Deserializer<&Value> = Deserializer(&*val); let access = crate::tag::TagAccess::new(parent, tag); return visitor.visit_enum(access); } 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(Deserializer(&x[0])), x @ Value::Text(..) => visitor.visit_enum(Deserializer(x)), _ => Err(de::Error::invalid_type(self.0.into(), &"map")), } } } impl<'a, 'de, T: Iterator> de::SeqAccess<'de> for Deserializer { type Error = Error; #[inline] fn next_element_seed>( &mut self, seed: U, ) -> Result, Self::Error> { match self.0.next() { None => Ok(None), Some(v) => seed.deserialize(Deserializer(v)).map(Some), } } } impl<'a, 'de, T: Iterator> de::MapAccess<'de> for Deserializer> { type Error = Error; #[inline] fn next_key_seed>( &mut self, seed: K, ) -> Result, Self::Error> { match self.0.peek() { None => Ok(None), Some(x) => Ok(Some(seed.deserialize(Deserializer(&x.0))?)), } } #[inline] fn next_value_seed>( &mut self, seed: V, ) -> Result { seed.deserialize(Deserializer(&self.0.next().unwrap().1)) } } impl<'a, 'de> de::EnumAccess<'de> for Deserializer<&'a (Value, Value)> { type Error = Error; type Variant = Deserializer<&'a Value>; #[inline] fn variant_seed>( self, seed: V, ) -> Result<(V::Value, Self::Variant), Self::Error> { let k = seed.deserialize(Deserializer(&self.0 .0))?; Ok((k, Deserializer(&self.0 .1))) } } impl<'a, 'de> de::EnumAccess<'de> for Deserializer<&'a Value> { type Error = Error; type Variant = Deserializer<&'a Value>; #[inline] fn variant_seed>( self, seed: V, ) -> Result<(V::Value, Self::Variant), Self::Error> { let k = seed.deserialize(self)?; Ok((k, Deserializer(&Value::Null))) } } impl<'a, 'de> de::VariantAccess<'de> for Deserializer<&'a 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>( self, seed: U, ) -> Result { seed.deserialize(self) } #[inline] fn tuple_variant>( self, _len: usize, visitor: V, ) -> Result { self.deserialize_seq(visitor) } #[inline] fn struct_variant>( self, _fields: &'static [&'static str], visitor: V, ) -> Result { self.deserialize_map(visitor) } } impl Value { /// Deserializes the `Value` into an object #[inline] pub fn deserialized<'de, T: de::Deserialize<'de>>(&self) -> Result { T::deserialize(Deserializer(self)) } }