summaryrefslogtreecommitdiffstats
path: root/vendor/ciborium/src/value/de.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
commitd1b2d29528b7794b41e66fc2136e395a02f8529b (patch)
treea4a17504b260206dec3cf55b2dca82929a348ac2 /vendor/ciborium/src/value/de.rs
parentReleasing progress-linux version 1.72.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.tar.xz
rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.zip
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/ciborium/src/value/de.rs')
-rw-r--r--vendor/ciborium/src/value/de.rs616
1 files changed, 616 insertions, 0 deletions
diff --git a/vendor/ciborium/src/value/de.rs b/vendor/ciborium/src/value/de.rs
new file mode 100644
index 000000000..63231905a
--- /dev/null
+++ b/vendor/ciborium/src/value/de.rs
@@ -0,0 +1,616 @@
+// 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<Integer> 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<E: de::Error>(self, v: $v) -> Result<Self::Value, E> {
+ 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<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)>::new();
+
+ 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 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<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 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<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+ deserializer.deserialize_any(Visitor)
+ }
+}
+
+struct Deserializer<T>(T);
+
+impl<'a> Deserializer<&'a Value> {
+ fn integer<N>(&self, kind: &'static str) -> Result<N, Error>
+ where
+ N: TryFrom<u128>,
+ N: TryFrom<i128>,
+ {
+ fn raw(value: &Value) -> Result<u128, Error> {
+ 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<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);
+ 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<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;
+ }
+
+ 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<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),
+ _ => 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> {
+ self.deserialize_map(visitor)
+ }
+
+ 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> {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_identifier<V: de::Visitor<'de>>(
+ self,
+ visitor: V,
+ ) -> Result<V::Value, Self::Error> {
+ self.deserialize_str(visitor)
+ }
+
+ 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> {
+ self.deserialize_unit(visitor)
+ }
+
+ #[inline]
+ fn deserialize_newtype_struct<V: de::Visitor<'de>>(
+ self,
+ _name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Self::Error> {
+ 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 == "@@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<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))
+ }
+}
+
+impl<'a, 'de> de::EnumAccess<'de> for Deserializer<&'a (Value, 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 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<V: de::DeserializeSeed<'de>>(
+ 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<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 {
+ /// Deserializes the `Value` into an object
+ #[inline]
+ pub fn deserialized<'de, T: de::Deserialize<'de>>(&self) -> Result<T, Error> {
+ T::deserialize(Deserializer(self))
+ }
+}