summaryrefslogtreecommitdiffstats
path: root/third_party/rust/serde_cbor/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/serde_cbor/src
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/serde_cbor/src')
-rw-r--r--third_party/rust/serde_cbor/src/de.rs1360
-rw-r--r--third_party/rust/serde_cbor/src/error.rs318
-rw-r--r--third_party/rust/serde_cbor/src/lib.rs369
-rw-r--r--third_party/rust/serde_cbor/src/read.rs637
-rw-r--r--third_party/rust/serde_cbor/src/ser.rs743
-rw-r--r--third_party/rust/serde_cbor/src/tags.rs220
-rw-r--r--third_party/rust/serde_cbor/src/value/de.rs166
-rw-r--r--third_party/rust/serde_cbor/src/value/mod.rs156
-rw-r--r--third_party/rust/serde_cbor/src/value/ser.rs443
-rw-r--r--third_party/rust/serde_cbor/src/write.rs175
10 files changed, 4587 insertions, 0 deletions
diff --git a/third_party/rust/serde_cbor/src/de.rs b/third_party/rust/serde_cbor/src/de.rs
new file mode 100644
index 0000000000..170e0593cf
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/de.rs
@@ -0,0 +1,1360 @@
+//! Deserialization.
+
+use core::f32;
+use core::marker::PhantomData;
+use core::result;
+use core::str;
+use half::f16;
+use serde::de;
+#[cfg(feature = "std")]
+use std::io;
+
+use crate::error::{Error, ErrorCode, Result};
+#[cfg(not(feature = "unsealed_read_write"))]
+use crate::read::EitherLifetime;
+#[cfg(feature = "unsealed_read_write")]
+pub use crate::read::EitherLifetime;
+#[cfg(feature = "std")]
+pub use crate::read::IoRead;
+use crate::read::Offset;
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub use crate::read::SliceRead;
+pub use crate::read::{MutSliceRead, Read, SliceReadFixed};
+#[cfg(feature = "tags")]
+use crate::tags::set_tag;
+/// Decodes a value from CBOR data in a slice.
+///
+/// # Examples
+///
+/// Deserialize a `String`
+///
+/// ```
+/// # use serde_cbor::de;
+/// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72];
+/// let value: String = de::from_slice(&v[..]).unwrap();
+/// assert_eq!(value, "foobar");
+/// ```
+///
+/// Deserialize a borrowed string with zero copies.
+///
+/// ```
+/// # use serde_cbor::de;
+/// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72];
+/// let value: &str = de::from_slice(&v[..]).unwrap();
+/// assert_eq!(value, "foobar");
+/// ```
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub fn from_slice<'a, T>(slice: &'a [u8]) -> Result<T>
+where
+ T: de::Deserialize<'a>,
+{
+ let mut deserializer = Deserializer::from_slice(slice);
+ let value = de::Deserialize::deserialize(&mut deserializer)?;
+ deserializer.end()?;
+ Ok(value)
+}
+
+// When the "std" feature is enabled there should be little to no need to ever use this function,
+// as `from_slice` covers all use cases (at the expense of being less efficient).
+/// Decode a value from CBOR data in a mutable slice.
+///
+/// This can be used in analogy to `from_slice`. Unlike `from_slice`, this will use the slice's
+/// mutability to rearrange data in it in order to resolve indefinite byte or text strings without
+/// resorting to allocations.
+pub fn from_mut_slice<'a, T>(slice: &'a mut [u8]) -> Result<T>
+where
+ T: de::Deserialize<'a>,
+{
+ let mut deserializer = Deserializer::from_mut_slice(slice);
+ let value = de::Deserialize::deserialize(&mut deserializer)?;
+ deserializer.end()?;
+ Ok(value)
+}
+
+// When the "std" feature is enabled there should be little to no need to ever use this function,
+// as `from_slice` covers all use cases and is much more reliable (at the expense of being less
+// efficient).
+/// Decode a value from CBOR data using a scratch buffer.
+///
+/// Users should generally prefer to use `from_slice` or `from_mut_slice` over this function,
+/// as decoding may fail when the scratch buffer turns out to be too small.
+///
+/// A realistic use case for this method would be decoding in a `no_std` environment from an
+/// immutable slice that is too large to copy.
+pub fn from_slice_with_scratch<'a, 'b, T>(slice: &'a [u8], scratch: &'b mut [u8]) -> Result<T>
+where
+ T: de::Deserialize<'a>,
+{
+ let mut deserializer = Deserializer::from_slice_with_scratch(slice, scratch);
+ let value = de::Deserialize::deserialize(&mut deserializer)?;
+ deserializer.end()?;
+ Ok(value)
+}
+
+/// Decodes a value from CBOR data in a reader.
+///
+/// # Examples
+///
+/// Deserialize a `String`
+///
+/// ```
+/// # use serde_cbor::de;
+/// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72];
+/// let value: String = de::from_reader(&v[..]).unwrap();
+/// assert_eq!(value, "foobar");
+/// ```
+///
+/// Note that `from_reader` cannot borrow data:
+///
+/// ```compile_fail
+/// # use serde_cbor::de;
+/// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72];
+/// let value: &str = de::from_reader(&v[..]).unwrap();
+/// assert_eq!(value, "foobar");
+/// ```
+#[cfg(feature = "std")]
+pub fn from_reader<T, R>(reader: R) -> Result<T>
+where
+ T: de::DeserializeOwned,
+ R: io::Read,
+{
+ let mut deserializer = Deserializer::from_reader(reader);
+ let value = de::Deserialize::deserialize(&mut deserializer)?;
+ deserializer.end()?;
+ Ok(value)
+}
+
+/// A Serde `Deserialize`r of CBOR data.
+#[derive(Debug)]
+pub struct Deserializer<R> {
+ read: R,
+ remaining_depth: u8,
+ accept_named: bool,
+ accept_packed: bool,
+ accept_standard_enums: bool,
+ accept_legacy_enums: bool,
+}
+
+#[cfg(feature = "std")]
+impl<R> Deserializer<IoRead<R>>
+where
+ R: io::Read,
+{
+ /// Constructs a `Deserializer` which reads from a `Read`er.
+ pub fn from_reader(reader: R) -> Deserializer<IoRead<R>> {
+ Deserializer::new(IoRead::new(reader))
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a> Deserializer<SliceRead<'a>> {
+ /// Constructs a `Deserializer` which reads from a slice.
+ ///
+ /// Borrowed strings and byte slices will be provided when possible.
+ pub fn from_slice(bytes: &'a [u8]) -> Deserializer<SliceRead<'a>> {
+ Deserializer::new(SliceRead::new(bytes))
+ }
+}
+
+impl<'a> Deserializer<MutSliceRead<'a>> {
+ /// Constructs a `Deserializer` which reads from a mutable slice that doubles as its own
+ /// scratch buffer.
+ ///
+ /// Borrowed strings and byte slices will be provided even for indefinite strings.
+ pub fn from_mut_slice(bytes: &'a mut [u8]) -> Deserializer<MutSliceRead<'a>> {
+ Deserializer::new(MutSliceRead::new(bytes))
+ }
+}
+
+impl<'a, 'b> Deserializer<SliceReadFixed<'a, 'b>> {
+ #[doc(hidden)]
+ pub fn from_slice_with_scratch(
+ bytes: &'a [u8],
+ scratch: &'b mut [u8],
+ ) -> Deserializer<SliceReadFixed<'a, 'b>> {
+ Deserializer::new(SliceReadFixed::new(bytes, scratch))
+ }
+}
+
+impl<'de, R> Deserializer<R>
+where
+ R: Read<'de>,
+{
+ /// Constructs a `Deserializer` from one of the possible serde_cbor input sources.
+ ///
+ /// `from_slice` and `from_reader` should normally be used instead of this method.
+ pub fn new(read: R) -> Self {
+ Deserializer {
+ read,
+ remaining_depth: 128,
+ accept_named: true,
+ accept_packed: true,
+ accept_standard_enums: true,
+ accept_legacy_enums: true,
+ }
+ }
+
+ /// Don't accept named variants and fields.
+ pub fn disable_named_format(mut self) -> Self {
+ self.accept_named = false;
+ self
+ }
+
+ /// Don't accept numbered variants and fields.
+ pub fn disable_packed_format(mut self) -> Self {
+ self.accept_packed = false;
+ self
+ }
+
+ /// Don't accept the new enum format used by `serde_cbor` versions >= v0.10.
+ pub fn disable_standard_enums(mut self) -> Self {
+ self.accept_standard_enums = false;
+ self
+ }
+
+ /// Don't accept the old enum format used by `serde_cbor` versions <= v0.9.
+ pub fn disable_legacy_enums(mut self) -> Self {
+ self.accept_legacy_enums = false;
+ self
+ }
+
+ /// This method should be called after a value has been deserialized to ensure there is no
+ /// trailing data in the input source.
+ pub fn end(&mut self) -> Result<()> {
+ match self.next()? {
+ Some(_) => Err(self.error(ErrorCode::TrailingData)),
+ None => Ok(()),
+ }
+ }
+
+ /// Turn a CBOR deserializer into an iterator over values of type T.
+ #[allow(clippy::should_implement_trait)] // Trait doesn't allow unconstrained T.
+ pub fn into_iter<T>(self) -> StreamDeserializer<'de, R, T>
+ where
+ T: de::Deserialize<'de>,
+ {
+ StreamDeserializer {
+ de: self,
+ output: PhantomData,
+ lifetime: PhantomData,
+ }
+ }
+
+ fn next(&mut self) -> Result<Option<u8>> {
+ self.read.next()
+ }
+
+ fn peek(&mut self) -> Result<Option<u8>> {
+ self.read.peek()
+ }
+
+ fn consume(&mut self) {
+ self.read.discard();
+ }
+
+ fn error(&self, reason: ErrorCode) -> Error {
+ let offset = self.read.offset();
+ Error::syntax(reason, offset)
+ }
+
+ fn parse_u8(&mut self) -> Result<u8> {
+ match self.next()? {
+ Some(byte) => Ok(byte),
+ None => Err(self.error(ErrorCode::EofWhileParsingValue)),
+ }
+ }
+
+ fn parse_u16(&mut self) -> Result<u16> {
+ let mut buf = [0; 2];
+ self.read
+ .read_into(&mut buf)
+ .map(|()| u16::from_be_bytes(buf))
+ }
+
+ fn parse_u32(&mut self) -> Result<u32> {
+ let mut buf = [0; 4];
+ self.read
+ .read_into(&mut buf)
+ .map(|()| u32::from_be_bytes(buf))
+ }
+
+ fn parse_u64(&mut self) -> Result<u64> {
+ let mut buf = [0; 8];
+ self.read
+ .read_into(&mut buf)
+ .map(|()| u64::from_be_bytes(buf))
+ }
+
+ fn parse_bytes<V>(&mut self, len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.read.read(len)? {
+ EitherLifetime::Long(buf) => visitor.visit_borrowed_bytes(buf),
+ EitherLifetime::Short(buf) => visitor.visit_bytes(buf),
+ }
+ }
+
+ fn parse_indefinite_bytes<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.read.clear_buffer();
+ loop {
+ let byte = self.parse_u8()?;
+ let len = match byte {
+ 0x40..=0x57 => byte as usize - 0x40,
+ 0x58 => self.parse_u8()? as usize,
+ 0x59 => self.parse_u16()? as usize,
+ 0x5a => self.parse_u32()? as usize,
+ 0x5b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ len as usize
+ }
+ 0xff => break,
+ _ => return Err(self.error(ErrorCode::UnexpectedCode)),
+ };
+
+ self.read.read_to_buffer(len)?;
+ }
+
+ match self.read.take_buffer() {
+ EitherLifetime::Long(buf) => visitor.visit_borrowed_bytes(buf),
+ EitherLifetime::Short(buf) => visitor.visit_bytes(buf),
+ }
+ }
+
+ fn convert_str<'a>(buf: &'a [u8], buf_end_offset: u64) -> Result<&'a str> {
+ match str::from_utf8(buf) {
+ Ok(s) => Ok(s),
+ Err(e) => {
+ let shift = buf.len() - e.valid_up_to();
+ let offset = buf_end_offset - shift as u64;
+ Err(Error::syntax(ErrorCode::InvalidUtf8, offset))
+ }
+ }
+ }
+
+ fn parse_str<V>(&mut self, len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ if let Some(offset) = self.read.offset().checked_add(len as u64) {
+ match self.read.read(len)? {
+ EitherLifetime::Long(buf) => {
+ let s = Self::convert_str(buf, offset)?;
+ visitor.visit_borrowed_str(s)
+ }
+ EitherLifetime::Short(buf) => {
+ let s = Self::convert_str(buf, offset)?;
+ visitor.visit_str(s)
+ }
+ }
+ } else {
+ // An overflow would have occured.
+ Err(Error::syntax(
+ ErrorCode::LengthOutOfRange,
+ self.read.offset(),
+ ))
+ }
+ }
+
+ fn parse_indefinite_str<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.read.clear_buffer();
+ loop {
+ let byte = self.parse_u8()?;
+ let len = match byte {
+ 0x60..=0x77 => byte as usize - 0x60,
+ 0x78 => self.parse_u8()? as usize,
+ 0x79 => self.parse_u16()? as usize,
+ 0x7a => self.parse_u32()? as usize,
+ 0x7b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ len as usize
+ }
+ 0xff => break,
+ _ => return Err(self.error(ErrorCode::UnexpectedCode)),
+ };
+
+ self.read.read_to_buffer(len)?;
+ }
+
+ let offset = self.read.offset();
+ match self.read.take_buffer() {
+ EitherLifetime::Long(buf) => {
+ let s = Self::convert_str(buf, offset)?;
+ visitor.visit_borrowed_str(s)
+ }
+ EitherLifetime::Short(buf) => {
+ let s = Self::convert_str(buf, offset)?;
+ visitor.visit_str(s)
+ }
+ }
+ }
+
+ #[cfg(feature = "tags")]
+ fn handle_tagged_value<V>(&mut self, tag: u64, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|d| {
+ set_tag(Some(tag));
+ let r = visitor.visit_newtype_struct(d);
+ set_tag(None);
+ r
+ })
+ }
+
+ #[cfg(not(feature = "tags"))]
+ fn handle_tagged_value<V>(&mut self, _tag: u64, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|de| de.parse_value(visitor))
+ }
+
+ fn recursion_checked<F, T>(&mut self, f: F) -> Result<T>
+ where
+ F: FnOnce(&mut Deserializer<R>) -> Result<T>,
+ {
+ self.remaining_depth -= 1;
+ if self.remaining_depth == 0 {
+ return Err(self.error(ErrorCode::RecursionLimitExceeded));
+ }
+ let r = f(self);
+ self.remaining_depth += 1;
+ r
+ }
+
+ fn parse_array<V>(&mut self, mut len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|de| {
+ let value = visitor.visit_seq(SeqAccess { de, len: &mut len })?;
+
+ if len != 0 {
+ Err(de.error(ErrorCode::TrailingData))
+ } else {
+ Ok(value)
+ }
+ })
+ }
+
+ fn parse_indefinite_array<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|de| {
+ let value = visitor.visit_seq(IndefiniteSeqAccess { de })?;
+ match de.next()? {
+ Some(0xff) => Ok(value),
+ Some(_) => Err(de.error(ErrorCode::TrailingData)),
+ None => Err(de.error(ErrorCode::EofWhileParsingArray)),
+ }
+ })
+ }
+
+ fn parse_map<V>(&mut self, mut len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let accept_packed = self.accept_packed;
+ let accept_named = self.accept_named;
+ self.recursion_checked(|de| {
+ let value = visitor.visit_map(MapAccess {
+ de,
+ len: &mut len,
+ accept_named,
+ accept_packed,
+ })?;
+
+ if len != 0 {
+ Err(de.error(ErrorCode::TrailingData))
+ } else {
+ Ok(value)
+ }
+ })
+ }
+
+ fn parse_indefinite_map<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let accept_named = self.accept_named;
+ let accept_packed = self.accept_packed;
+ self.recursion_checked(|de| {
+ let value = visitor.visit_map(IndefiniteMapAccess {
+ de,
+ accept_packed,
+ accept_named,
+ })?;
+ match de.next()? {
+ Some(0xff) => Ok(value),
+ Some(_) => Err(de.error(ErrorCode::TrailingData)),
+ None => Err(de.error(ErrorCode::EofWhileParsingMap)),
+ }
+ })
+ }
+
+ fn parse_enum<V>(&mut self, mut len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|de| {
+ let value = visitor.visit_enum(VariantAccess {
+ seq: SeqAccess { de, len: &mut len },
+ })?;
+
+ if len != 0 {
+ Err(de.error(ErrorCode::TrailingData))
+ } else {
+ Ok(value)
+ }
+ })
+ }
+
+ fn parse_enum_map<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let accept_named = self.accept_named;
+ let accept_packed = self.accept_packed;
+ self.recursion_checked(|de| {
+ let mut len = 1;
+ let value = visitor.visit_enum(VariantAccessMap {
+ map: MapAccess {
+ de,
+ len: &mut len,
+ accept_packed,
+ accept_named,
+ },
+ })?;
+
+ if len != 0 {
+ Err(de.error(ErrorCode::TrailingData))
+ } else {
+ Ok(value)
+ }
+ })
+ }
+
+ fn parse_indefinite_enum<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|de| {
+ let value = visitor.visit_enum(VariantAccess {
+ seq: IndefiniteSeqAccess { de },
+ })?;
+ match de.next()? {
+ Some(0xff) => Ok(value),
+ Some(_) => Err(de.error(ErrorCode::TrailingData)),
+ None => Err(de.error(ErrorCode::EofWhileParsingArray)),
+ }
+ })
+ }
+
+ fn parse_f16(&mut self) -> Result<f32> {
+ Ok(f32::from(f16::from_bits(self.parse_u16()?)))
+ }
+
+ fn parse_f32(&mut self) -> Result<f32> {
+ self.parse_u32().map(|i| f32::from_bits(i))
+ }
+
+ fn parse_f64(&mut self) -> Result<f64> {
+ self.parse_u64().map(|i| f64::from_bits(i))
+ }
+
+ // Don't warn about the `unreachable!` in case
+ // exhaustive integer pattern matching is enabled.
+ #[allow(unreachable_patterns)]
+ fn parse_value<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let byte = self.parse_u8()?;
+ match byte {
+ // Major type 0: an unsigned integer
+ 0x00..=0x17 => visitor.visit_u8(byte),
+ 0x18 => {
+ let value = self.parse_u8()?;
+ visitor.visit_u8(value)
+ }
+ 0x19 => {
+ let value = self.parse_u16()?;
+ visitor.visit_u16(value)
+ }
+ 0x1a => {
+ let value = self.parse_u32()?;
+ visitor.visit_u32(value)
+ }
+ 0x1b => {
+ let value = self.parse_u64()?;
+ visitor.visit_u64(value)
+ }
+ 0x1c..=0x1f => Err(self.error(ErrorCode::UnassignedCode)),
+
+ // Major type 1: a negative integer
+ 0x20..=0x37 => visitor.visit_i8(-1 - (byte - 0x20) as i8),
+ 0x38 => {
+ let value = self.parse_u8()?;
+ visitor.visit_i16(-1 - i16::from(value))
+ }
+ 0x39 => {
+ let value = self.parse_u16()?;
+ visitor.visit_i32(-1 - i32::from(value))
+ }
+ 0x3a => {
+ let value = self.parse_u32()?;
+ visitor.visit_i64(-1 - i64::from(value))
+ }
+ 0x3b => {
+ let value = self.parse_u64()?;
+ if value > i64::max_value() as u64 {
+ return visitor.visit_i128(-1 - i128::from(value));
+ }
+ visitor.visit_i64(-1 - value as i64)
+ }
+ 0x3c..=0x3f => Err(self.error(ErrorCode::UnassignedCode)),
+
+ // Major type 2: a byte string
+ 0x40..=0x57 => self.parse_bytes(byte as usize - 0x40, visitor),
+ 0x58 => {
+ let len = self.parse_u8()?;
+ self.parse_bytes(len as usize, visitor)
+ }
+ 0x59 => {
+ let len = self.parse_u16()?;
+ self.parse_bytes(len as usize, visitor)
+ }
+ 0x5a => {
+ let len = self.parse_u32()?;
+ self.parse_bytes(len as usize, visitor)
+ }
+ 0x5b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ self.parse_bytes(len as usize, visitor)
+ }
+ 0x5c..=0x5e => Err(self.error(ErrorCode::UnassignedCode)),
+ 0x5f => self.parse_indefinite_bytes(visitor),
+
+ // Major type 3: a text string
+ 0x60..=0x77 => self.parse_str(byte as usize - 0x60, visitor),
+ 0x78 => {
+ let len = self.parse_u8()?;
+ self.parse_str(len as usize, visitor)
+ }
+ 0x79 => {
+ let len = self.parse_u16()?;
+ self.parse_str(len as usize, visitor)
+ }
+ 0x7a => {
+ let len = self.parse_u32()?;
+ self.parse_str(len as usize, visitor)
+ }
+ 0x7b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ self.parse_str(len as usize, visitor)
+ }
+ 0x7c..=0x7e => Err(self.error(ErrorCode::UnassignedCode)),
+ 0x7f => self.parse_indefinite_str(visitor),
+
+ // Major type 4: an array of data items
+ 0x80..=0x97 => self.parse_array(byte as usize - 0x80, visitor),
+ 0x98 => {
+ let len = self.parse_u8()?;
+ self.parse_array(len as usize, visitor)
+ }
+ 0x99 => {
+ let len = self.parse_u16()?;
+ self.parse_array(len as usize, visitor)
+ }
+ 0x9a => {
+ let len = self.parse_u32()?;
+ self.parse_array(len as usize, visitor)
+ }
+ 0x9b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ self.parse_array(len as usize, visitor)
+ }
+ 0x9c..=0x9e => Err(self.error(ErrorCode::UnassignedCode)),
+ 0x9f => self.parse_indefinite_array(visitor),
+
+ // Major type 5: a map of pairs of data items
+ 0xa0..=0xb7 => self.parse_map(byte as usize - 0xa0, visitor),
+ 0xb8 => {
+ let len = self.parse_u8()?;
+ self.parse_map(len as usize, visitor)
+ }
+ 0xb9 => {
+ let len = self.parse_u16()?;
+ self.parse_map(len as usize, visitor)
+ }
+ 0xba => {
+ let len = self.parse_u32()?;
+ self.parse_map(len as usize, visitor)
+ }
+ 0xbb => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ self.parse_map(len as usize, visitor)
+ }
+ 0xbc..=0xbe => Err(self.error(ErrorCode::UnassignedCode)),
+ 0xbf => self.parse_indefinite_map(visitor),
+
+ // Major type 6: optional semantic tagging of other major types
+ 0xc0..=0xd7 => {
+ let tag = u64::from(byte) - 0xc0;
+ self.handle_tagged_value(tag, visitor)
+ }
+ 0xd8 => {
+ let tag = self.parse_u8()?;
+ self.handle_tagged_value(tag.into(), visitor)
+ }
+ 0xd9 => {
+ let tag = self.parse_u16()?;
+ self.handle_tagged_value(tag.into(), visitor)
+ }
+ 0xda => {
+ let tag = self.parse_u32()?;
+ self.handle_tagged_value(tag.into(), visitor)
+ }
+ 0xdb => {
+ let tag = self.parse_u64()?;
+ self.handle_tagged_value(tag, visitor)
+ }
+ 0xdc..=0xdf => Err(self.error(ErrorCode::UnassignedCode)),
+
+ // Major type 7: floating-point numbers and other simple data types that need no content
+ 0xe0..=0xf3 => Err(self.error(ErrorCode::UnassignedCode)),
+ 0xf4 => visitor.visit_bool(false),
+ 0xf5 => visitor.visit_bool(true),
+ 0xf6 => visitor.visit_unit(),
+ 0xf7 => visitor.visit_unit(),
+ 0xf8 => Err(self.error(ErrorCode::UnassignedCode)),
+ 0xf9 => {
+ let value = self.parse_f16()?;
+ visitor.visit_f32(value)
+ }
+ 0xfa => {
+ let value = self.parse_f32()?;
+ visitor.visit_f32(value)
+ }
+ 0xfb => {
+ let value = self.parse_f64()?;
+ visitor.visit_f64(value)
+ }
+ 0xfc..=0xfe => Err(self.error(ErrorCode::UnassignedCode)),
+ 0xff => Err(self.error(ErrorCode::UnexpectedCode)),
+
+ _ => unreachable!(),
+ }
+ }
+}
+
+impl<'de, 'a, R> de::Deserializer<'de> for &'a mut Deserializer<R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.parse_value(visitor)
+ }
+
+ #[inline]
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.peek()? {
+ Some(0xf6) => {
+ self.consume();
+ visitor.visit_none()
+ }
+ _ => visitor.visit_some(self),
+ }
+ }
+
+ #[inline]
+ fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_newtype_struct(self)
+ }
+
+ // Unit variants are encoded as just the variant identifier.
+ // Tuple variants are encoded as an array of the variant identifier followed by the fields.
+ // Struct variants are encoded as an array of the variant identifier followed by the struct.
+ #[inline]
+ fn deserialize_enum<V>(
+ self,
+ _name: &str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.peek()? {
+ Some(byte @ 0x80..=0x9f) => {
+ if !self.accept_legacy_enums {
+ return Err(self.error(ErrorCode::WrongEnumFormat));
+ }
+ self.consume();
+ match byte {
+ 0x80..=0x97 => self.parse_enum(byte as usize - 0x80, visitor),
+ 0x98 => {
+ let len = self.parse_u8()?;
+ self.parse_enum(len as usize, visitor)
+ }
+ 0x99 => {
+ let len = self.parse_u16()?;
+ self.parse_enum(len as usize, visitor)
+ }
+ 0x9a => {
+ let len = self.parse_u32()?;
+ self.parse_enum(len as usize, visitor)
+ }
+ 0x9b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ self.parse_enum(len as usize, visitor)
+ }
+ 0x9c..=0x9e => Err(self.error(ErrorCode::UnassignedCode)),
+ 0x9f => self.parse_indefinite_enum(visitor),
+
+ _ => unreachable!(),
+ }
+ }
+ Some(0xa1) => {
+ if !self.accept_standard_enums {
+ return Err(self.error(ErrorCode::WrongEnumFormat));
+ }
+ self.consume();
+ self.parse_enum_map(visitor)
+ }
+ None => Err(self.error(ErrorCode::EofWhileParsingValue)),
+ _ => {
+ if !self.accept_standard_enums && !self.accept_legacy_enums {
+ return Err(self.error(ErrorCode::WrongEnumFormat));
+ }
+ visitor.visit_enum(UnitVariantAccess { de: self })
+ }
+ }
+ }
+
+ #[inline]
+ fn is_human_readable(&self) -> bool {
+ false
+ }
+
+ serde::forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string unit
+ unit_struct seq tuple tuple_struct map struct identifier ignored_any
+ bytes byte_buf
+ }
+}
+
+impl<R> Deserializer<R>
+where
+ R: Offset,
+{
+ /// Return the current offset in the reader
+ #[inline]
+ pub fn byte_offset(&self) -> usize {
+ self.read.byte_offset()
+ }
+}
+
+trait MakeError {
+ fn error(&self, code: ErrorCode) -> Error;
+}
+
+struct SeqAccess<'a, R> {
+ de: &'a mut Deserializer<R>,
+ len: &'a mut usize,
+}
+
+impl<'de, 'a, R> de::SeqAccess<'de> for SeqAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ if *self.len == 0 {
+ return Ok(None);
+ }
+ *self.len -= 1;
+
+ let value = seed.deserialize(&mut *self.de)?;
+ Ok(Some(value))
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ Some(*self.len)
+ }
+}
+
+impl<'de, 'a, R> MakeError for SeqAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ fn error(&self, code: ErrorCode) -> Error {
+ self.de.error(code)
+ }
+}
+
+struct IndefiniteSeqAccess<'a, R> {
+ de: &'a mut Deserializer<R>,
+}
+
+impl<'de, 'a, R> de::SeqAccess<'de> for IndefiniteSeqAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match self.de.peek()? {
+ Some(0xff) => return Ok(None),
+ Some(_) => {}
+ None => return Err(self.de.error(ErrorCode::EofWhileParsingArray)),
+ }
+
+ let value = seed.deserialize(&mut *self.de)?;
+ Ok(Some(value))
+ }
+}
+
+impl<'de, 'a, R> MakeError for IndefiniteSeqAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ fn error(&self, code: ErrorCode) -> Error {
+ self.de.error(code)
+ }
+}
+
+struct MapAccess<'a, R> {
+ de: &'a mut Deserializer<R>,
+ len: &'a mut usize,
+ accept_named: bool,
+ accept_packed: bool,
+}
+
+impl<'de, 'a, R> de::MapAccess<'de> for MapAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
+ where
+ K: de::DeserializeSeed<'de>,
+ {
+ if *self.len == 0 {
+ return Ok(None);
+ }
+ *self.len -= 1;
+
+ match self.de.peek()? {
+ Some(_byte @ 0x00..=0x1b) if !self.accept_packed => {
+ return Err(self.de.error(ErrorCode::WrongStructFormat));
+ }
+ Some(_byte @ 0x60..=0x7f) if !self.accept_named => {
+ return Err(self.de.error(ErrorCode::WrongStructFormat));
+ }
+ _ => {}
+ };
+
+ let value = seed.deserialize(&mut *self.de)?;
+ Ok(Some(value))
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(&mut *self.de)
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ Some(*self.len)
+ }
+}
+
+impl<'de, 'a, R> MakeError for MapAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ fn error(&self, code: ErrorCode) -> Error {
+ self.de.error(code)
+ }
+}
+
+struct IndefiniteMapAccess<'a, R> {
+ de: &'a mut Deserializer<R>,
+ accept_packed: bool,
+ accept_named: bool,
+}
+
+impl<'de, 'a, R> de::MapAccess<'de> for IndefiniteMapAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
+ where
+ K: de::DeserializeSeed<'de>,
+ {
+ match self.de.peek()? {
+ Some(_byte @ 0x00..=0x1b) if !self.accept_packed => {
+ return Err(self.de.error(ErrorCode::WrongStructFormat))
+ }
+ Some(_byte @ 0x60..=0x7f) if !self.accept_named => {
+ return Err(self.de.error(ErrorCode::WrongStructFormat))
+ }
+ Some(0xff) => return Ok(None),
+ Some(_) => {}
+ None => return Err(self.de.error(ErrorCode::EofWhileParsingMap)),
+ }
+
+ let value = seed.deserialize(&mut *self.de)?;
+ Ok(Some(value))
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(&mut *self.de)
+ }
+}
+
+struct UnitVariantAccess<'a, R> {
+ de: &'a mut Deserializer<R>,
+}
+
+impl<'de, 'a, R> de::EnumAccess<'de> for UnitVariantAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+ type Variant = UnitVariantAccess<'a, R>;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, UnitVariantAccess<'a, R>)>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ let variant = seed.deserialize(&mut *self.de)?;
+ Ok((variant, self))
+ }
+}
+
+impl<'de, 'a, R> de::VariantAccess<'de> for UnitVariantAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<()> {
+ Ok(())
+ }
+
+ fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"newtype variant",
+ ))
+ }
+
+ fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"tuple variant",
+ ))
+ }
+
+ fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"struct variant",
+ ))
+ }
+}
+
+struct VariantAccess<T> {
+ seq: T,
+}
+
+impl<'de, T> de::EnumAccess<'de> for VariantAccess<T>
+where
+ T: de::SeqAccess<'de, Error = Error> + MakeError,
+{
+ type Error = Error;
+ type Variant = VariantAccess<T>;
+
+ fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, VariantAccess<T>)>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ let variant = match self.seq.next_element_seed(seed) {
+ Ok(Some(variant)) => variant,
+ Ok(None) => return Err(self.seq.error(ErrorCode::ArrayTooShort)),
+ Err(e) => return Err(e),
+ };
+ Ok((variant, self))
+ }
+}
+
+impl<'de, T> de::VariantAccess<'de> for VariantAccess<T>
+where
+ T: de::SeqAccess<'de, Error = Error> + MakeError,
+{
+ type Error = Error;
+
+ fn unit_variant(mut self) -> Result<()> {
+ match self.seq.next_element() {
+ Ok(Some(())) => Ok(()),
+ Ok(None) => Err(self.seq.error(ErrorCode::ArrayTooLong)),
+ Err(e) => Err(e),
+ }
+ }
+
+ fn newtype_variant_seed<S>(mut self, seed: S) -> Result<S::Value>
+ where
+ S: de::DeserializeSeed<'de>,
+ {
+ match self.seq.next_element_seed(seed) {
+ Ok(Some(variant)) => Ok(variant),
+ Ok(None) => Err(self.seq.error(ErrorCode::ArrayTooShort)),
+ Err(e) => Err(e),
+ }
+ }
+
+ fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_seq(self.seq)
+ }
+
+ fn struct_variant<V>(mut self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let seed = StructVariantSeed { visitor };
+ match self.seq.next_element_seed(seed) {
+ Ok(Some(variant)) => Ok(variant),
+ Ok(None) => Err(self.seq.error(ErrorCode::ArrayTooShort)),
+ Err(e) => Err(e),
+ }
+ }
+}
+
+struct StructVariantSeed<V> {
+ visitor: V,
+}
+
+impl<'de, V> de::DeserializeSeed<'de> for StructVariantSeed<V>
+where
+ V: de::Visitor<'de>,
+{
+ type Value = V::Value;
+
+ fn deserialize<D>(self, de: D) -> result::Result<V::Value, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ de.deserialize_any(self.visitor)
+ }
+}
+
+/// Iterator that deserializes a stream into multiple CBOR values.
+///
+/// A stream deserializer can be created from any CBOR deserializer using the
+/// `Deserializer::into_iter` method.
+///
+/// ```
+/// # extern crate serde_cbor;
+/// use serde_cbor::de::Deserializer;
+/// use serde_cbor::value::Value;
+///
+/// # fn main() {
+/// let data: Vec<u8> = vec![
+/// 0x01, 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72,
+/// ];
+/// let mut it = Deserializer::from_slice(&data[..]).into_iter::<Value>();
+/// assert_eq!(
+/// Value::Integer(1),
+/// it.next().unwrap().unwrap()
+/// );
+/// assert_eq!(
+/// Value::Text("foobar".to_string()),
+/// it.next().unwrap().unwrap()
+/// );
+/// # }
+/// ```
+#[derive(Debug)]
+pub struct StreamDeserializer<'de, R, T> {
+ de: Deserializer<R>,
+ output: PhantomData<T>,
+ lifetime: PhantomData<&'de ()>,
+}
+
+impl<'de, R, T> StreamDeserializer<'de, R, T>
+where
+ R: Read<'de>,
+ T: de::Deserialize<'de>,
+{
+ /// Create a new CBOR stream deserializer from one of the possible
+ /// serde_cbor input sources.
+ ///
+ /// Typically it is more convenient to use one of these methods instead:
+ ///
+ /// * `Deserializer::from_slice(...).into_iter()`
+ /// * `Deserializer::from_reader(...).into_iter()`
+ pub fn new(read: R) -> StreamDeserializer<'de, R, T> {
+ StreamDeserializer {
+ de: Deserializer::new(read),
+ output: PhantomData,
+ lifetime: PhantomData,
+ }
+ }
+}
+
+impl<'de, R, T> StreamDeserializer<'de, R, T>
+where
+ R: Offset,
+ T: de::Deserialize<'de>,
+{
+ /// Return the current offset in the reader
+ #[inline]
+ pub fn byte_offset(&self) -> usize {
+ self.de.byte_offset()
+ }
+}
+
+impl<'de, R, T> Iterator for StreamDeserializer<'de, R, T>
+where
+ R: Read<'de>,
+ T: de::Deserialize<'de>,
+{
+ type Item = Result<T>;
+
+ fn next(&mut self) -> Option<Result<T>> {
+ match self.de.peek() {
+ Ok(Some(_)) => Some(T::deserialize(&mut self.de)),
+ Ok(None) => None,
+ Err(e) => Some(Err(e)),
+ }
+ }
+}
+
+struct VariantAccessMap<T> {
+ map: T,
+}
+
+impl<'de, T> de::EnumAccess<'de> for VariantAccessMap<T>
+where
+ T: de::MapAccess<'de, Error = Error> + MakeError,
+{
+ type Error = Error;
+ type Variant = VariantAccessMap<T>;
+
+ fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, VariantAccessMap<T>)>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ let variant = match self.map.next_key_seed(seed) {
+ Ok(Some(variant)) => variant,
+ Ok(None) => return Err(self.map.error(ErrorCode::ArrayTooShort)),
+ Err(e) => return Err(e),
+ };
+ Ok((variant, self))
+ }
+}
+
+impl<'de, T> de::VariantAccess<'de> for VariantAccessMap<T>
+where
+ T: de::MapAccess<'de, Error = Error> + MakeError,
+{
+ type Error = Error;
+
+ fn unit_variant(mut self) -> Result<()> {
+ match self.map.next_value() {
+ Ok(()) => Ok(()),
+ Err(e) => Err(e),
+ }
+ }
+
+ fn newtype_variant_seed<S>(mut self, seed: S) -> Result<S::Value>
+ where
+ S: de::DeserializeSeed<'de>,
+ {
+ self.map.next_value_seed(seed)
+ }
+
+ fn tuple_variant<V>(mut self, _len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let seed = StructVariantSeed { visitor };
+ self.map.next_value_seed(seed)
+ }
+
+ fn struct_variant<V>(mut self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let seed = StructVariantSeed { visitor };
+ self.map.next_value_seed(seed)
+ }
+}
diff --git a/third_party/rust/serde_cbor/src/error.rs b/third_party/rust/serde_cbor/src/error.rs
new file mode 100644
index 0000000000..b1a6a459e5
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/error.rs
@@ -0,0 +1,318 @@
+//! When serializing or deserializing CBOR goes wrong.
+use core::fmt;
+use core::result;
+use serde::de;
+use serde::ser;
+#[cfg(feature = "std")]
+use std::error;
+#[cfg(feature = "std")]
+use std::io;
+
+/// This type represents all possible errors that can occur when serializing or deserializing CBOR
+/// data.
+pub struct Error(ErrorImpl);
+
+/// Alias for a `Result` with the error type `serde_cbor::Error`.
+pub type Result<T> = result::Result<T, Error>;
+
+/// Categorizes the cause of a `serde_cbor::Error`.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Category {
+ /// The error was caused by a failure to read or write bytes on an IO stream.
+ Io,
+ /// The error was caused by input that was not syntactically valid CBOR.
+ Syntax,
+ /// The error was caused by input data that was semantically incorrect.
+ Data,
+ /// The error was caused by prematurely reaching the end of the input data.
+ Eof,
+}
+
+impl Error {
+ /// The byte offset at which the error occurred.
+ pub fn offset(&self) -> u64 {
+ self.0.offset
+ }
+
+ pub(crate) fn syntax(code: ErrorCode, offset: u64) -> Error {
+ Error(ErrorImpl { code, offset })
+ }
+
+ #[cfg(feature = "std")]
+ pub(crate) fn io(error: io::Error) -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::Io(error),
+ offset: 0,
+ })
+ }
+
+ #[cfg(all(not(feature = "std"), feature = "unsealed_read_write"))]
+ /// Creates an error signalling that the underlying `Read` encountered an I/O error.
+ pub fn io() -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::Io,
+ offset: 0,
+ })
+ }
+
+ #[cfg(feature = "unsealed_read_write")]
+ /// Creates an error signalling that the scratch buffer was too small to fit the data.
+ pub fn scratch_too_small(offset: u64) -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::ScratchTooSmall,
+ offset,
+ })
+ }
+
+ #[cfg(not(feature = "unsealed_read_write"))]
+ pub(crate) fn scratch_too_small(offset: u64) -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::ScratchTooSmall,
+ offset,
+ })
+ }
+
+ #[cfg(feature = "unsealed_read_write")]
+ /// Creates an error with a custom message.
+ ///
+ /// **Note**: When the "std" feature is disabled, the message will be discarded.
+ pub fn message<T: fmt::Display>(_msg: T) -> Error {
+ #[cfg(not(feature = "std"))]
+ {
+ Error(ErrorImpl {
+ code: ErrorCode::Message,
+ offset: 0,
+ })
+ }
+ #[cfg(feature = "std")]
+ {
+ Error(ErrorImpl {
+ code: ErrorCode::Message(_msg.to_string()),
+ offset: 0,
+ })
+ }
+ }
+
+ #[cfg(not(feature = "unsealed_read_write"))]
+ pub(crate) fn message<T: fmt::Display>(_msg: T) -> Error {
+ #[cfg(not(feature = "std"))]
+ {
+ Error(ErrorImpl {
+ code: ErrorCode::Message,
+ offset: 0,
+ })
+ }
+ #[cfg(feature = "std")]
+ {
+ Error(ErrorImpl {
+ code: ErrorCode::Message(_msg.to_string()),
+ offset: 0,
+ })
+ }
+ }
+
+ #[cfg(feature = "unsealed_read_write")]
+ /// Creates an error signalling that the underlying read
+ /// encountered an end of input.
+ pub fn eof(offset: u64) -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::EofWhileParsingValue,
+ offset,
+ })
+ }
+
+ /// Categorizes the cause of this error.
+ pub fn classify(&self) -> Category {
+ match self.0.code {
+ #[cfg(feature = "std")]
+ ErrorCode::Message(_) => Category::Data,
+ #[cfg(not(feature = "std"))]
+ ErrorCode::Message => Category::Data,
+ #[cfg(feature = "std")]
+ ErrorCode::Io(_) => Category::Io,
+ #[cfg(not(feature = "std"))]
+ ErrorCode::Io => Category::Io,
+ ErrorCode::ScratchTooSmall => Category::Io,
+ ErrorCode::EofWhileParsingValue
+ | ErrorCode::EofWhileParsingArray
+ | ErrorCode::EofWhileParsingMap => Category::Eof,
+ ErrorCode::LengthOutOfRange
+ | ErrorCode::InvalidUtf8
+ | ErrorCode::UnassignedCode
+ | ErrorCode::UnexpectedCode
+ | ErrorCode::TrailingData
+ | ErrorCode::ArrayTooShort
+ | ErrorCode::ArrayTooLong
+ | ErrorCode::RecursionLimitExceeded
+ | ErrorCode::WrongEnumFormat
+ | ErrorCode::WrongStructFormat => Category::Syntax,
+ }
+ }
+
+ /// Returns true if this error was caused by a failure to read or write bytes on an IO stream.
+ pub fn is_io(&self) -> bool {
+ match self.classify() {
+ Category::Io => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if this error was caused by input that was not syntactically valid CBOR.
+ pub fn is_syntax(&self) -> bool {
+ match self.classify() {
+ Category::Syntax => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if this error was caused by data that was semantically incorrect.
+ pub fn is_data(&self) -> bool {
+ match self.classify() {
+ Category::Data => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if this error was caused by prematurely reaching the end of the input data.
+ pub fn is_eof(&self) -> bool {
+ match self.classify() {
+ Category::Eof => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if this error was caused by the scratch buffer being too small.
+ ///
+ /// Note this being `true` implies that `is_io()` is also `true`.
+ pub fn is_scratch_too_small(&self) -> bool {
+ match self.0.code {
+ ErrorCode::ScratchTooSmall => true,
+ _ => false,
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl error::Error for Error {
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+ match self.0.code {
+ ErrorCode::Io(ref err) => Some(err),
+ _ => None,
+ }
+ }
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ if self.0.offset == 0 {
+ fmt::Display::fmt(&self.0.code, f)
+ } else {
+ write!(f, "{} at offset {}", self.0.code, self.0.offset)
+ }
+ }
+}
+
+impl fmt::Debug for Error {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Debug::fmt(&self.0, fmt)
+ }
+}
+
+impl de::Error for Error {
+ fn custom<T: fmt::Display>(msg: T) -> Error {
+ Error::message(msg)
+ }
+
+ fn invalid_type(unexp: de::Unexpected<'_>, exp: &dyn de::Expected) -> Error {
+ if let de::Unexpected::Unit = unexp {
+ Error::custom(format_args!("invalid type: null, expected {}", exp))
+ } else {
+ Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
+ }
+ }
+}
+
+impl ser::Error for Error {
+ fn custom<T: fmt::Display>(msg: T) -> Error {
+ Error::message(msg)
+ }
+}
+
+#[cfg(feature = "std")]
+impl From<io::Error> for Error {
+ fn from(e: io::Error) -> Error {
+ Error::io(e)
+ }
+}
+
+#[cfg(not(feature = "std"))]
+impl From<core::fmt::Error> for Error {
+ fn from(_: core::fmt::Error) -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::Message,
+ offset: 0,
+ })
+ }
+}
+
+#[derive(Debug)]
+struct ErrorImpl {
+ code: ErrorCode,
+ offset: u64,
+}
+
+#[derive(Debug)]
+pub(crate) enum ErrorCode {
+ #[cfg(feature = "std")]
+ Message(String),
+ #[cfg(not(feature = "std"))]
+ Message,
+ #[cfg(feature = "std")]
+ Io(io::Error),
+ #[allow(unused)]
+ #[cfg(not(feature = "std"))]
+ Io,
+ ScratchTooSmall,
+ EofWhileParsingValue,
+ EofWhileParsingArray,
+ EofWhileParsingMap,
+ LengthOutOfRange,
+ InvalidUtf8,
+ UnassignedCode,
+ UnexpectedCode,
+ TrailingData,
+ ArrayTooShort,
+ ArrayTooLong,
+ RecursionLimitExceeded,
+ WrongEnumFormat,
+ WrongStructFormat,
+}
+
+impl fmt::Display for ErrorCode {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ #[cfg(feature = "std")]
+ ErrorCode::Message(ref msg) => f.write_str(msg),
+ #[cfg(not(feature = "std"))]
+ ErrorCode::Message => f.write_str("Unknown error"),
+ #[cfg(feature = "std")]
+ ErrorCode::Io(ref err) => fmt::Display::fmt(err, f),
+ #[cfg(not(feature = "std"))]
+ ErrorCode::Io => f.write_str("Unknown I/O error"),
+ ErrorCode::ScratchTooSmall => f.write_str("Scratch buffer too small"),
+ ErrorCode::EofWhileParsingValue => f.write_str("EOF while parsing a value"),
+ ErrorCode::EofWhileParsingArray => f.write_str("EOF while parsing an array"),
+ ErrorCode::EofWhileParsingMap => f.write_str("EOF while parsing a map"),
+ ErrorCode::LengthOutOfRange => f.write_str("length out of range"),
+ ErrorCode::InvalidUtf8 => f.write_str("invalid UTF-8"),
+ ErrorCode::UnassignedCode => f.write_str("unassigned type"),
+ ErrorCode::UnexpectedCode => f.write_str("unexpected code"),
+ ErrorCode::TrailingData => f.write_str("trailing data"),
+ ErrorCode::ArrayTooShort => f.write_str("array too short"),
+ ErrorCode::ArrayTooLong => f.write_str("array too long"),
+ ErrorCode::RecursionLimitExceeded => f.write_str("recursion limit exceeded"),
+ ErrorCode::WrongEnumFormat => f.write_str("wrong enum format"),
+ ErrorCode::WrongStructFormat => f.write_str("wrong struct format"),
+ }
+ }
+}
diff --git a/third_party/rust/serde_cbor/src/lib.rs b/third_party/rust/serde_cbor/src/lib.rs
new file mode 100644
index 0000000000..5566854153
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/lib.rs
@@ -0,0 +1,369 @@
+//! CBOR and serialization.
+//!
+//! # Usage
+//!
+//! Serde CBOR supports Rust 1.40 and up. Add this to your `Cargo.toml`:
+//! ```toml
+//! [dependencies]
+//! serde_cbor = "0.10"
+//! ```
+//!
+//! Storing and loading Rust types is easy and requires only
+//! minimal modifications to the program code.
+//!
+//! ```rust
+//! use serde_derive::{Deserialize, Serialize};
+//! use std::error::Error;
+//! use std::fs::File;
+//!
+//! // Types annotated with `Serialize` can be stored as CBOR.
+//! // To be able to load them again add `Deserialize`.
+//! #[derive(Debug, Serialize, Deserialize)]
+//! struct Mascot {
+//! name: String,
+//! species: String,
+//! year_of_birth: u32,
+//! }
+//!
+//! fn main() -> Result<(), Box<dyn Error>> {
+//! let ferris = Mascot {
+//! name: "Ferris".to_owned(),
+//! species: "crab".to_owned(),
+//! year_of_birth: 2015,
+//! };
+//!
+//! let ferris_file = File::create("examples/ferris.cbor")?;
+//! // Write Ferris to the given file.
+//! // Instead of a file you can use any type that implements `io::Write`
+//! // like a HTTP body, database connection etc.
+//! serde_cbor::to_writer(ferris_file, &ferris)?;
+//!
+//! let tux_file = File::open("examples/tux.cbor")?;
+//! // Load Tux from a file.
+//! // Serde CBOR performs roundtrip serialization meaning that
+//! // the data will not change in any way.
+//! let tux: Mascot = serde_cbor::from_reader(tux_file)?;
+//!
+//! println!("{:?}", tux);
+//! // prints: Mascot { name: "Tux", species: "penguin", year_of_birth: 1996 }
+//!
+//! Ok(())
+//! }
+//! ```
+//!
+//! There are a lot of options available to customize the format.
+//! To operate on untyped CBOR values have a look at the `Value` type.
+//!
+//! # Type-based Serialization and Deserialization
+//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
+//! from CBOR via the serialization API. To be able to serialize a piece of data, it must implement
+//! the `serde::Serialize` trait. To be able to deserialize a piece of data, it must implement the
+//! `serde::Deserialize` trait. Serde provides an annotation to automatically generate the
+//! code for these traits: `#[derive(Serialize, Deserialize)]`.
+//!
+//! The CBOR API also provides an enum `serde_cbor::Value`.
+//!
+//! # Packed Encoding
+//! When serializing structs or enums in CBOR the keys or enum variant names will be serialized
+//! as string keys to a map. Especially in embedded environments this can increase the file
+//! size too much. In packed encoding all struct keys, as well as any enum variant that has no data,
+//! will be serialized as variable sized integers. The first 24 entries in any struct consume only a
+//! single byte! Packed encoding uses serde's preferred [externally tagged enum
+//! format](https://serde.rs/enum-representations.html) and therefore serializes enum variant names
+//! as string keys when that variant contains data. So, in the packed encoding example, `FirstVariant`
+//! encodes to a single byte, but encoding `SecondVariant` requires 16 bytes.
+//!
+//! To serialize a document in this format use `Serializer::new(writer).packed_format()` or
+//! the shorthand `ser::to_vec_packed`. The deserialization works without any changes.
+//!
+//! If you would like to omit the enum variant encoding for all variants, including ones that
+//! contain data, you can add `legacy_enums()` in addition to `packed_format()`, as can seen
+//! in the Serialize using minimal encoding example.
+//!
+//! # Self describing documents
+//! In some contexts different formats are used but there is no way to declare the format used
+//! out of band. For this reason CBOR has a magic number that may be added before any document.
+//! Self describing documents are created with `serializer.self_describe()`.
+//!
+//! # Examples
+//! Read a CBOR value that is known to be a map of string keys to string values and print it.
+//!
+//! ```rust
+//! use std::collections::BTreeMap;
+//! use serde_cbor::from_slice;
+//!
+//! let slice = b"\xa5aaaAabaBacaCadaDaeaE";
+//! let value: BTreeMap<String, String> = from_slice(slice).unwrap();
+//! println!("{:?}", value); // {"e": "E", "d": "D", "a": "A", "c": "C", "b": "B"}
+//! ```
+//!
+//! Read a general CBOR value with an unknown content.
+//!
+//! ```rust
+//! use serde_cbor::from_slice;
+//! use serde_cbor::value::Value;
+//!
+//! let slice = b"\x82\x01\xa1aaab";
+//! let value: Value = from_slice(slice).unwrap();
+//! println!("{:?}", value); // Array([U64(1), Object({String("a"): String("b")})])
+//! ```
+//!
+//! Serialize an object.
+//!
+//! ```rust
+//! use std::collections::BTreeMap;
+//! use serde_cbor::to_vec;
+//!
+//! let mut programming_languages = BTreeMap::new();
+//! programming_languages.insert("rust", vec!["safe", "concurrent", "fast"]);
+//! programming_languages.insert("python", vec!["powerful", "friendly", "open"]);
+//! programming_languages.insert("js", vec!["lightweight", "interpreted", "object-oriented"]);
+//! let encoded = to_vec(&programming_languages);
+//! assert_eq!(encoded.unwrap().len(), 103);
+//! ```
+//!
+//! Deserializing data in the middle of a slice
+//! ```
+//! # extern crate serde_cbor;
+//! use serde_cbor::Deserializer;
+//!
+//! # fn main() {
+//! let data: Vec<u8> = vec![
+//! 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x66, 0x66, 0x6f, 0x6f, 0x62,
+//! 0x61, 0x72,
+//! ];
+//! let mut deserializer = Deserializer::from_slice(&data);
+//! let value: &str = serde::de::Deserialize::deserialize(&mut deserializer)
+//! .unwrap();
+//! let rest = &data[deserializer.byte_offset()..];
+//! assert_eq!(value, "foobar");
+//! assert_eq!(rest, &[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
+//! # }
+//! ```
+//!
+//! Serialize using packed encoding
+//!
+//! ```rust
+//! use serde_derive::{Deserialize, Serialize};
+//! use serde_cbor::ser::to_vec_packed;
+//! use WithTwoVariants::*;
+//!
+//! #[derive(Debug, Serialize, Deserialize)]
+//! enum WithTwoVariants {
+//! FirstVariant,
+//! SecondVariant(u8),
+//! }
+//!
+//! let cbor = to_vec_packed(&FirstVariant).unwrap();
+//! assert_eq!(cbor.len(), 1);
+//!
+//! let cbor = to_vec_packed(&SecondVariant(0)).unwrap();
+//! assert_eq!(cbor.len(), 16); // Includes 13 bytes of "SecondVariant"
+//! ```
+//!
+//! Serialize using minimal encoding
+//!
+//! ```rust
+//! use serde_derive::{Deserialize, Serialize};
+//! use serde_cbor::{Result, Serializer, ser::{self, IoWrite}};
+//! use WithTwoVariants::*;
+//!
+//! fn to_vec_minimal<T>(value: &T) -> Result<Vec<u8>>
+//! where
+//! T: serde::Serialize,
+//! {
+//! let mut vec = Vec::new();
+//! value.serialize(&mut Serializer::new(&mut IoWrite::new(&mut vec)).packed_format().legacy_enums())?;
+//! Ok(vec)
+//! }
+//!
+//! #[derive(Debug, Serialize, Deserialize)]
+//! enum WithTwoVariants {
+//! FirstVariant,
+//! SecondVariant(u8),
+//! }
+//!
+//! let cbor = to_vec_minimal(&FirstVariant).unwrap();
+//! assert_eq!(cbor.len(), 1);
+//!
+//! let cbor = to_vec_minimal(&SecondVariant(0)).unwrap();
+//! assert_eq!(cbor.len(), 3);
+//! ```
+//!
+//! # `no-std` support
+//!
+//! Serde CBOR supports building in a `no_std` context, use the following lines
+//! in your `Cargo.toml` dependencies:
+//! ``` toml
+//! [dependencies]
+//! serde = { version = "1.0", default-features = false }
+//! serde_cbor = { version = "0.10", default-features = false }
+//! ```
+//!
+//! Without the `std` feature the functions [from_reader], [from_slice], [to_vec], and [to_writer]
+//! are not exported. To export [from_slice] and [to_vec] enable the `alloc` feature. The `alloc`
+//! feature uses the [`alloc` library][alloc-lib] and requires at least version 1.36.0 of Rust.
+//!
+//! [alloc-lib]: https://doc.rust-lang.org/alloc/
+//!
+//! *Note*: to use derive macros in serde you will need to declare `serde`
+//! dependency like so:
+//! ``` toml
+//! serde = { version = "1.0", default-features = false, features = ["derive"] }
+//! ```
+//!
+//! Serialize an object with `no_std` and without `alloc`.
+//! ``` rust
+//! # #[macro_use] extern crate serde_derive;
+//! # fn main() -> Result<(), serde_cbor::Error> {
+//! use serde::Serialize;
+//! use serde_cbor::Serializer;
+//! use serde_cbor::ser::SliceWrite;
+//!
+//! #[derive(Serialize)]
+//! struct User {
+//! user_id: u32,
+//! password_hash: [u8; 4],
+//! }
+//!
+//! let mut buf = [0u8; 100];
+//! let writer = SliceWrite::new(&mut buf[..]);
+//! let mut ser = Serializer::new(writer);
+//! let user = User {
+//! user_id: 42,
+//! password_hash: [1, 2, 3, 4],
+//! };
+//! user.serialize(&mut ser)?;
+//! let writer = ser.into_inner();
+//! let size = writer.bytes_written();
+//! let expected = [
+//! 0xa2, 0x67, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x2a, 0x6d,
+//! 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73,
+//! 0x68, 0x84, 0x1, 0x2, 0x3, 0x4
+//! ];
+//! assert_eq!(&buf[..size], expected);
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! Deserialize an object.
+//! ``` rust
+//! # #[macro_use] extern crate serde_derive;
+//! # fn main() -> Result<(), serde_cbor::Error> {
+//! #[derive(Debug, PartialEq, Deserialize)]
+//! struct User {
+//! user_id: u32,
+//! password_hash: [u8; 4],
+//! }
+//!
+//! let value = [
+//! 0xa2, 0x67, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x2a, 0x6d,
+//! 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73,
+//! 0x68, 0x84, 0x1, 0x2, 0x3, 0x4
+//! ];
+//!
+//! // from_slice_with_scratch will not alter input data, use it whenever you
+//! // borrow from somewhere else.
+//! // You will have to size your scratch according to the input data you
+//! // expect.
+//! use serde_cbor::de::from_slice_with_scratch;
+//! let mut scratch = [0u8; 32];
+//! let user: User = from_slice_with_scratch(&value[..], &mut scratch)?;
+//! assert_eq!(user, User {
+//! user_id: 42,
+//! password_hash: [1, 2, 3, 4],
+//! });
+//!
+//! let mut value = [
+//! 0xa2, 0x67, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x2a, 0x6d,
+//! 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73,
+//! 0x68, 0x84, 0x1, 0x2, 0x3, 0x4
+//! ];
+//!
+//! // from_mut_slice will move data around the input slice, you may only use it
+//! // on data you may own or can modify.
+//! use serde_cbor::de::from_mut_slice;
+//! let user: User = from_mut_slice(&mut value[..])?;
+//! assert_eq!(user, User {
+//! user_id: 42,
+//! password_hash: [1, 2, 3, 4],
+//! });
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! # Limitations
+//!
+//! While Serde CBOR strives to support all features of Serde and CBOR
+//! there are a few limitations.
+//!
+//! * [Tags] are ignored during deserialization and can't be emitted during
+//! serialization. This is because Serde has no concept of tagged
+//! values. See:&nbsp;[#3]
+//! * Unknown [simple values] cause an `UnassignedCode` error.
+//! The simple values *False* and *True* are recognized and parsed as bool.
+//! *Null* and *Undefined* are both deserialized as *unit*.
+//! The *unit* type is serialized as *Null*. See:&nbsp;[#86]
+//! * [128-bit integers] can't be directly encoded in CBOR. If you need them
+//! store them as a byte string. See:&nbsp;[#77]
+//!
+//! [Tags]: https://tools.ietf.org/html/rfc7049#section-2.4.4
+//! [#3]: https://github.com/pyfisch/cbor/issues/3
+//! [simple values]: https://tools.ietf.org/html/rfc7049#section-3.5
+//! [#86]: https://github.com/pyfisch/cbor/issues/86
+//! [128-bit integers]: https://doc.rust-lang.org/std/primitive.u128.html
+//! [#77]: https://github.com/pyfisch/cbor/issues/77
+
+#![deny(missing_docs)]
+#![cfg_attr(not(feature = "std"), no_std)]
+
+// When we are running tests in no_std mode we need to explicitly link std, because `cargo test`
+// will not work without it.
+#[cfg(all(not(feature = "std"), test))]
+extern crate std;
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+pub mod de;
+pub mod error;
+mod read;
+pub mod ser;
+pub mod tags;
+mod write;
+
+#[cfg(feature = "std")]
+pub mod value;
+
+// Re-export the [items recommended by serde](https://serde.rs/conventions.html).
+#[doc(inline)]
+pub use crate::de::{Deserializer, StreamDeserializer};
+
+#[doc(inline)]
+pub use crate::error::{Error, Result};
+
+#[doc(inline)]
+pub use crate::ser::Serializer;
+
+// Convenience functions for serialization and deserialization.
+// These functions are only available in `std` mode.
+#[cfg(feature = "std")]
+#[doc(inline)]
+pub use crate::de::from_reader;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+#[doc(inline)]
+pub use crate::de::from_slice;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+#[doc(inline)]
+pub use crate::ser::to_vec;
+
+#[cfg(feature = "std")]
+#[doc(inline)]
+pub use crate::ser::to_writer;
+
+// Re-export the value type like serde_json
+#[cfg(feature = "std")]
+#[doc(inline)]
+pub use crate::value::Value;
diff --git a/third_party/rust/serde_cbor/src/read.rs b/third_party/rust/serde_cbor/src/read.rs
new file mode 100644
index 0000000000..1b53018df8
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/read.rs
@@ -0,0 +1,637 @@
+#[cfg(feature = "alloc")]
+use alloc::{vec, vec::Vec};
+#[cfg(feature = "std")]
+use core::cmp;
+use core::mem;
+
+#[cfg(feature = "std")]
+use std::io::{self, Read as StdRead};
+
+use crate::error::{Error, ErrorCode, Result};
+
+#[cfg(not(feature = "unsealed_read_write"))]
+/// Trait used by the deserializer for iterating over input.
+///
+/// This trait is sealed by default, enabling the `unsealed_read_write` feature removes this bound
+/// to allow objects outside of this crate to implement this trait.
+pub trait Read<'de>: private::Sealed {
+ #[doc(hidden)]
+ /// Read n bytes from the input.
+ ///
+ /// Implementations that can are asked to return a slice with a Long lifetime that outlives the
+ /// decoder, but others (eg. ones that need to allocate the data into a temporary buffer) can
+ /// return it with a Short lifetime that just lives for the time of read's mutable borrow of
+ /// the reader.
+ ///
+ /// This may, as a side effect, clear the reader's scratch buffer (as the provided
+ /// implementation does).
+
+ // A more appropriate lifetime setup for this (that would allow the Deserializer::convert_str
+ // to stay a function) would be something like `fn read<'a, 'r: 'a>(&'a mut 'r immut self, ...) -> ...
+ // EitherLifetime<'r, 'de>>`, which borrows self mutably for the duration of the function and
+ // downgrates that reference to an immutable one that outlives the result (protecting the
+ // scratch buffer from changes), but alas, that can't be expressed (yet?).
+ fn read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>> {
+ self.clear_buffer();
+ self.read_to_buffer(n)?;
+
+ Ok(self.take_buffer())
+ }
+
+ #[doc(hidden)]
+ fn next(&mut self) -> Result<Option<u8>>;
+
+ #[doc(hidden)]
+ fn peek(&mut self) -> Result<Option<u8>>;
+
+ #[doc(hidden)]
+ fn clear_buffer(&mut self);
+
+ #[doc(hidden)]
+ fn read_to_buffer(&mut self, n: usize) -> Result<()>;
+
+ #[doc(hidden)]
+ fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>;
+
+ #[doc(hidden)]
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()>;
+
+ #[doc(hidden)]
+ fn discard(&mut self);
+
+ #[doc(hidden)]
+ fn offset(&self) -> u64;
+}
+
+#[cfg(feature = "unsealed_read_write")]
+/// Trait used by the deserializer for iterating over input.
+pub trait Read<'de> {
+ /// Read n bytes from the input.
+ ///
+ /// Implementations that can are asked to return a slice with a Long lifetime that outlives the
+ /// decoder, but others (eg. ones that need to allocate the data into a temporary buffer) can
+ /// return it with a Short lifetime that just lives for the time of read's mutable borrow of
+ /// the reader.
+ ///
+ /// This may, as a side effect, clear the reader's scratch buffer (as the provided
+ /// implementation does).
+
+ // A more appropriate lifetime setup for this (that would allow the Deserializer::convert_str
+ // to stay a function) would be something like `fn read<'a, 'r: 'a>(&'a mut 'r immut self, ...) -> ...
+ // EitherLifetime<'r, 'de>>`, which borrows self mutably for the duration of the function and
+ // downgrates that reference to an immutable one that outlives the result (protecting the
+ // scratch buffer from changes), but alas, that can't be expressed (yet?).
+ fn read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>> {
+ self.clear_buffer();
+ self.read_to_buffer(n)?;
+
+ Ok(self.take_buffer())
+ }
+
+ /// Read the next byte from the input, if any.
+ fn next(&mut self) -> Result<Option<u8>>;
+
+ /// Peek at the next byte of the input, if any. This does not advance the reader, so the result
+ /// of this function will remain the same until a read or clear occurs.
+ fn peek(&mut self) -> Result<Option<u8>>;
+
+ /// Clear the underlying scratch buffer
+ fn clear_buffer(&mut self);
+
+ /// Append n bytes from the reader to the reader's scratch buffer (without clearing it)
+ fn read_to_buffer(&mut self, n: usize) -> Result<()>;
+
+ /// Read out everything accumulated in the reader's scratch buffer. This may, as a side effect,
+ /// clear it.
+ fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>;
+
+ /// Read from the input until `buf` is full or end of input is encountered.
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()>;
+
+ /// Discard any data read by `peek`.
+ fn discard(&mut self);
+
+ /// Returns the offset from the start of the reader.
+ fn offset(&self) -> u64;
+}
+
+/// Represents a reader that can return its current position
+pub trait Offset {
+ fn byte_offset(&self) -> usize;
+}
+
+/// Represents a buffer with one of two lifetimes.
+pub enum EitherLifetime<'short, 'long> {
+ /// The short lifetime
+ Short(&'short [u8]),
+ /// The long lifetime
+ Long(&'long [u8]),
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+mod private {
+ pub trait Sealed {}
+}
+
+/// CBOR input source that reads from a std::io input stream.
+#[cfg(feature = "std")]
+#[derive(Debug)]
+pub struct IoRead<R>
+where
+ R: io::Read,
+{
+ reader: OffsetReader<R>,
+ scratch: Vec<u8>,
+ ch: Option<u8>,
+}
+
+#[cfg(feature = "std")]
+impl<R> IoRead<R>
+where
+ R: io::Read,
+{
+ /// Creates a new CBOR input source to read from a std::io input stream.
+ pub fn new(reader: R) -> IoRead<R> {
+ IoRead {
+ reader: OffsetReader { reader, offset: 0 },
+ scratch: vec![],
+ ch: None,
+ }
+ }
+
+ #[inline]
+ fn next_inner(&mut self) -> Result<Option<u8>> {
+ let mut buf = [0; 1];
+ loop {
+ match self.reader.read(&mut buf) {
+ Ok(0) => return Ok(None),
+ Ok(_) => return Ok(Some(buf[0])),
+ Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
+ Err(e) => return Err(Error::io(e)),
+ }
+ }
+ }
+}
+
+#[cfg(all(feature = "std", not(feature = "unsealed_read_write")))]
+impl<R> private::Sealed for IoRead<R> where R: io::Read {}
+
+#[cfg(feature = "std")]
+impl<'de, R> Read<'de> for IoRead<R>
+where
+ R: io::Read,
+{
+ #[inline]
+ fn next(&mut self) -> Result<Option<u8>> {
+ match self.ch.take() {
+ Some(ch) => Ok(Some(ch)),
+ None => self.next_inner(),
+ }
+ }
+
+ #[inline]
+ fn peek(&mut self) -> Result<Option<u8>> {
+ match self.ch {
+ Some(ch) => Ok(Some(ch)),
+ None => {
+ self.ch = self.next_inner()?;
+ Ok(self.ch)
+ }
+ }
+ }
+
+ fn read_to_buffer(&mut self, mut n: usize) -> Result<()> {
+ // defend against malicious input pretending to be huge strings by limiting growth
+ self.scratch.reserve(cmp::min(n, 16 * 1024));
+
+ if n == 0 {
+ return Ok(());
+ }
+
+ if let Some(ch) = self.ch.take() {
+ self.scratch.push(ch);
+ n -= 1;
+ }
+
+ // n == 0 is OK here and needs no further special treatment
+
+ let transfer_result = {
+ // Prepare for take() (which consumes its reader) by creating a reference adaptor
+ // that'll only live in this block
+ let reference = self.reader.by_ref();
+ // Append the first n bytes of the reader to the scratch vector (or up to
+ // an error or EOF indicated by a shorter read)
+ let mut taken = reference.take(n as u64);
+ taken.read_to_end(&mut self.scratch)
+ };
+
+ match transfer_result {
+ Ok(r) if r == n => Ok(()),
+ Ok(_) => Err(Error::syntax(
+ ErrorCode::EofWhileParsingValue,
+ self.offset(),
+ )),
+ Err(e) => Err(Error::io(e)),
+ }
+ }
+
+ fn clear_buffer(&mut self) {
+ self.scratch.clear();
+ }
+
+ fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de> {
+ EitherLifetime::Short(&self.scratch)
+ }
+
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
+ self.reader.read_exact(buf).map_err(|e| {
+ if e.kind() == io::ErrorKind::UnexpectedEof {
+ Error::syntax(ErrorCode::EofWhileParsingValue, self.offset())
+ } else {
+ Error::io(e)
+ }
+ })
+ }
+
+ #[inline]
+ fn discard(&mut self) {
+ self.ch = None;
+ }
+
+ fn offset(&self) -> u64 {
+ self.reader.offset
+ }
+}
+
+#[cfg(feature = "std")]
+impl<R> Offset for IoRead<R>
+where
+ R: std::io::Read,
+{
+ fn byte_offset(&self) -> usize {
+ self.offset() as usize
+ }
+}
+
+#[cfg(feature = "std")]
+#[derive(Debug)]
+struct OffsetReader<R> {
+ reader: R,
+ offset: u64,
+}
+
+#[cfg(feature = "std")]
+impl<R> io::Read for OffsetReader<R>
+where
+ R: io::Read,
+{
+ #[inline]
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ let r = self.reader.read(buf);
+ if let Ok(count) = r {
+ self.offset += count as u64;
+ }
+ r
+ }
+}
+
+/// A CBOR input source that reads from a slice of bytes.
+#[cfg(any(feature = "std", feature = "alloc"))]
+#[derive(Debug)]
+pub struct SliceRead<'a> {
+ slice: &'a [u8],
+ scratch: Vec<u8>,
+ index: usize,
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a> SliceRead<'a> {
+ /// Creates a CBOR input source to read from a slice of bytes.
+ pub fn new(slice: &'a [u8]) -> SliceRead<'a> {
+ SliceRead {
+ slice,
+ scratch: vec![],
+ index: 0,
+ }
+ }
+
+ fn end(&self, n: usize) -> Result<usize> {
+ match self.index.checked_add(n) {
+ Some(end) if end <= self.slice.len() => Ok(end),
+ _ => Err(Error::syntax(
+ ErrorCode::EofWhileParsingValue,
+ self.slice.len() as u64,
+ )),
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a> Offset for SliceRead<'a> {
+ #[inline]
+ fn byte_offset(&self) -> usize {
+ self.index
+ }
+}
+
+#[cfg(all(
+ any(feature = "std", feature = "alloc"),
+ not(feature = "unsealed_read_write")
+))]
+impl<'a> private::Sealed for SliceRead<'a> {}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a> Read<'a> for SliceRead<'a> {
+ #[inline]
+ fn next(&mut self) -> Result<Option<u8>> {
+ Ok(if self.index < self.slice.len() {
+ let ch = self.slice[self.index];
+ self.index += 1;
+ Some(ch)
+ } else {
+ None
+ })
+ }
+
+ #[inline]
+ fn peek(&mut self) -> Result<Option<u8>> {
+ Ok(if self.index < self.slice.len() {
+ Some(self.slice[self.index])
+ } else {
+ None
+ })
+ }
+
+ fn clear_buffer(&mut self) {
+ self.scratch.clear();
+ }
+
+ fn read_to_buffer(&mut self, n: usize) -> Result<()> {
+ let end = self.end(n)?;
+ let slice = &self.slice[self.index..end];
+ self.scratch.extend_from_slice(slice);
+ self.index = end;
+
+ Ok(())
+ }
+
+ #[inline]
+ fn read<'b>(&'b mut self, n: usize) -> Result<EitherLifetime<'b, 'a>> {
+ let end = self.end(n)?;
+ let slice = &self.slice[self.index..end];
+ self.index = end;
+ Ok(EitherLifetime::Long(slice))
+ }
+
+ fn take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a> {
+ EitherLifetime::Short(&self.scratch)
+ }
+
+ #[inline]
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
+ let end = self.end(buf.len())?;
+ buf.copy_from_slice(&self.slice[self.index..end]);
+ self.index = end;
+ Ok(())
+ }
+
+ #[inline]
+ fn discard(&mut self) {
+ self.index += 1;
+ }
+
+ fn offset(&self) -> u64 {
+ self.index as u64
+ }
+}
+
+/// A CBOR input source that reads from a slice of bytes using a fixed size scratch buffer.
+///
+/// [`SliceRead`](struct.SliceRead.html) and [`MutSliceRead`](struct.MutSliceRead.html) are usually
+/// preferred over this, as they can handle indefinite length items.
+#[derive(Debug)]
+pub struct SliceReadFixed<'a, 'b> {
+ slice: &'a [u8],
+ scratch: &'b mut [u8],
+ index: usize,
+ scratch_index: usize,
+}
+
+impl<'a, 'b> SliceReadFixed<'a, 'b> {
+ /// Creates a CBOR input source to read from a slice of bytes, backed by a scratch buffer.
+ pub fn new(slice: &'a [u8], scratch: &'b mut [u8]) -> SliceReadFixed<'a, 'b> {
+ SliceReadFixed {
+ slice,
+ scratch,
+ index: 0,
+ scratch_index: 0,
+ }
+ }
+
+ fn end(&self, n: usize) -> Result<usize> {
+ match self.index.checked_add(n) {
+ Some(end) if end <= self.slice.len() => Ok(end),
+ _ => Err(Error::syntax(
+ ErrorCode::EofWhileParsingValue,
+ self.slice.len() as u64,
+ )),
+ }
+ }
+
+ fn scratch_end(&self, n: usize) -> Result<usize> {
+ match self.scratch_index.checked_add(n) {
+ Some(end) if end <= self.scratch.len() => Ok(end),
+ _ => Err(Error::scratch_too_small(self.index as u64)),
+ }
+ }
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+impl<'a, 'b> private::Sealed for SliceReadFixed<'a, 'b> {}
+
+impl<'a, 'b> Read<'a> for SliceReadFixed<'a, 'b> {
+ #[inline]
+ fn next(&mut self) -> Result<Option<u8>> {
+ Ok(if self.index < self.slice.len() {
+ let ch = self.slice[self.index];
+ self.index += 1;
+ Some(ch)
+ } else {
+ None
+ })
+ }
+
+ #[inline]
+ fn peek(&mut self) -> Result<Option<u8>> {
+ Ok(if self.index < self.slice.len() {
+ Some(self.slice[self.index])
+ } else {
+ None
+ })
+ }
+
+ fn clear_buffer(&mut self) {
+ self.scratch_index = 0;
+ }
+
+ fn read_to_buffer(&mut self, n: usize) -> Result<()> {
+ let end = self.end(n)?;
+ let scratch_end = self.scratch_end(n)?;
+ let slice = &self.slice[self.index..end];
+ self.scratch[self.scratch_index..scratch_end].copy_from_slice(&slice);
+ self.index = end;
+ self.scratch_index = scratch_end;
+
+ Ok(())
+ }
+
+ fn read<'c>(&'c mut self, n: usize) -> Result<EitherLifetime<'c, 'a>> {
+ let end = self.end(n)?;
+ let slice = &self.slice[self.index..end];
+ self.index = end;
+ Ok(EitherLifetime::Long(slice))
+ }
+
+ fn take_buffer<'c>(&'c mut self) -> EitherLifetime<'c, 'a> {
+ EitherLifetime::Short(&self.scratch[0..self.scratch_index])
+ }
+
+ #[inline]
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
+ let end = self.end(buf.len())?;
+ buf.copy_from_slice(&self.slice[self.index..end]);
+ self.index = end;
+ Ok(())
+ }
+
+ #[inline]
+ fn discard(&mut self) {
+ self.index += 1;
+ }
+
+ fn offset(&self) -> u64 {
+ self.index as u64
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'b> Offset for SliceReadFixed<'a, 'b> {
+ #[inline]
+ fn byte_offset(&self) -> usize {
+ self.index
+ }
+}
+
+/// A CBOR input source that reads from a slice of bytes, and can move data around internally to
+/// reassemble indefinite strings without the need of an allocated scratch buffer.
+#[derive(Debug)]
+pub struct MutSliceRead<'a> {
+ /// A complete view of the reader's data. It is promised that bytes before buffer_end are not
+ /// mutated any more.
+ slice: &'a mut [u8],
+ /// Read cursor position in slice
+ index: usize,
+ /// Number of bytes already discarded from the slice
+ before: usize,
+ /// End of the buffer area that contains all bytes read_into_buffer. This is always <= index.
+ buffer_end: usize,
+}
+
+impl<'a> MutSliceRead<'a> {
+ /// Creates a CBOR input source to read from a slice of bytes.
+ pub fn new(slice: &'a mut [u8]) -> MutSliceRead<'a> {
+ MutSliceRead {
+ slice,
+ index: 0,
+ before: 0,
+ buffer_end: 0,
+ }
+ }
+
+ fn end(&self, n: usize) -> Result<usize> {
+ match self.index.checked_add(n) {
+ Some(end) if end <= self.slice.len() => Ok(end),
+ _ => Err(Error::syntax(
+ ErrorCode::EofWhileParsingValue,
+ self.slice.len() as u64,
+ )),
+ }
+ }
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+impl<'a> private::Sealed for MutSliceRead<'a> {}
+
+impl<'a> Read<'a> for MutSliceRead<'a> {
+ #[inline]
+ fn next(&mut self) -> Result<Option<u8>> {
+ // This is duplicated from SliceRead, can that be eased?
+ Ok(if self.index < self.slice.len() {
+ let ch = self.slice[self.index];
+ self.index += 1;
+ Some(ch)
+ } else {
+ None
+ })
+ }
+
+ #[inline]
+ fn peek(&mut self) -> Result<Option<u8>> {
+ // This is duplicated from SliceRead, can that be eased?
+ Ok(if self.index < self.slice.len() {
+ Some(self.slice[self.index])
+ } else {
+ None
+ })
+ }
+
+ fn clear_buffer(&mut self) {
+ self.slice = &mut mem::replace(&mut self.slice, &mut [])[self.index..];
+ self.before += self.index;
+ self.index = 0;
+ self.buffer_end = 0;
+ }
+
+ fn read_to_buffer(&mut self, n: usize) -> Result<()> {
+ let end = self.end(n)?;
+ debug_assert!(
+ self.buffer_end <= self.index,
+ "MutSliceRead invariant violated: scratch buffer exceeds index"
+ );
+ self.slice[self.buffer_end..end].rotate_left(self.index - self.buffer_end);
+ self.buffer_end += n;
+ self.index = end;
+
+ Ok(())
+ }
+
+ fn take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a> {
+ let (left, right) = mem::replace(&mut self.slice, &mut []).split_at_mut(self.index);
+ self.slice = right;
+ self.before += self.index;
+ self.index = 0;
+
+ let left = &left[..self.buffer_end];
+ self.buffer_end = 0;
+
+ EitherLifetime::Long(left)
+ }
+
+ #[inline]
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
+ // This is duplicated from SliceRead, can that be eased?
+ let end = self.end(buf.len())?;
+ buf.copy_from_slice(&self.slice[self.index..end]);
+ self.index = end;
+ Ok(())
+ }
+
+ #[inline]
+ fn discard(&mut self) {
+ self.index += 1;
+ }
+
+ fn offset(&self) -> u64 {
+ (self.before + self.index) as u64
+ }
+}
diff --git a/third_party/rust/serde_cbor/src/ser.rs b/third_party/rust/serde_cbor/src/ser.rs
new file mode 100644
index 0000000000..7016dc340a
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/ser.rs
@@ -0,0 +1,743 @@
+//! Serialize a Rust data structure to CBOR data.
+
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+
+#[cfg(feature = "std")]
+pub use crate::write::IoWrite;
+pub use crate::write::{SliceWrite, Write};
+
+use crate::error::{Error, Result};
+use half::f16;
+use serde::ser::{self, Serialize};
+#[cfg(feature = "std")]
+use std::io;
+
+use crate::tags::{get_tag, CBOR_NEWTYPE_NAME};
+
+/// Serializes a value to a vector.
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
+where
+ T: ser::Serialize,
+{
+ let mut vec = Vec::new();
+ value.serialize(&mut Serializer::new(&mut vec))?;
+ Ok(vec)
+}
+
+/// Serializes a value to a vector in packed format.
+#[cfg(feature = "std")]
+pub fn to_vec_packed<T>(value: &T) -> Result<Vec<u8>>
+where
+ T: ser::Serialize,
+{
+ let mut vec = Vec::new();
+ value.serialize(&mut Serializer::new(&mut IoWrite::new(&mut vec)).packed_format())?;
+ Ok(vec)
+}
+
+/// Serializes a value to a writer.
+#[cfg(feature = "std")]
+pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
+where
+ W: io::Write,
+ T: ser::Serialize,
+{
+ value.serialize(&mut Serializer::new(&mut IoWrite::new(writer)))
+}
+
+/// A structure for serializing Rust values to CBOR.
+#[derive(Debug)]
+pub struct Serializer<W> {
+ writer: W,
+ packed: bool,
+ enum_as_map: bool,
+}
+
+impl<W> Serializer<W>
+where
+ W: Write,
+{
+ /// Creates a new CBOR serializer.
+ ///
+ /// `to_vec` and `to_writer` should normally be used instead of this method.
+ #[inline]
+ pub fn new(writer: W) -> Self {
+ Serializer {
+ writer,
+ packed: false,
+ enum_as_map: true,
+ }
+ }
+
+ /// Choose concise/packed format for serializer.
+ ///
+ /// In the packed format enum variant names and field names
+ /// are replaced with numeric indizes to conserve space.
+ pub fn packed_format(mut self) -> Self {
+ self.packed = true;
+ self
+ }
+
+ /// Enable old enum format used by `serde_cbor` versions <= v0.9.
+ ///
+ /// The `legacy_enums` option determines how enums are encoded.
+ ///
+ /// This makes no difference when encoding and decoding enums using
+ /// this crate, but it shows up when decoding to a `Value` or decoding
+ /// in other languages.
+ ///
+ /// # Examples
+ ///
+ /// Given the following enum
+ ///
+ /// ```rust
+ /// enum Enum {
+ /// Unit,
+ /// NewType(i32),
+ /// Tuple(String, bool),
+ /// Struct{ x: i32, y: i32 },
+ /// }
+ /// ```
+ /// we will give the `Value` with the same encoding for each case using
+ /// JSON notation.
+ ///
+ /// ## Default encodings
+ ///
+ /// * `Enum::Unit` encodes as `"Unit"`
+ /// * `Enum::NewType(10)` encodes as `{"NewType": 10}`
+ /// * `Enum::Tuple("x", true)` encodes as `{"Tuple": ["x", true]}`
+ ///
+ /// ## Legacy encodings
+ ///
+ /// * `Enum::Unit` encodes as `"Unit"`
+ /// * `Enum::NewType(10)` encodes as `["NewType", 10]`
+ /// * `Enum::Tuple("x", true)` encodes as `["Tuple", "x", true]`
+ /// * `Enum::Struct{ x: 5, y: -5 }` encodes as `["Struct", {"x": 5, "y": -5}]`
+ pub fn legacy_enums(mut self) -> Self {
+ self.enum_as_map = false;
+ self
+ }
+
+ /// Writes a CBOR self-describe tag to the stream.
+ ///
+ /// Tagging allows a decoder to distinguish different file formats based on their content
+ /// without further information.
+ #[inline]
+ pub fn self_describe(&mut self) -> Result<()> {
+ let mut buf = [6 << 5 | 25, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&55799u16.to_be_bytes());
+ self.writer.write_all(&buf).map_err(|e| e.into())
+ }
+
+ /// Unwrap the `Writer` from the `Serializer`.
+ #[inline]
+ pub fn into_inner(self) -> W {
+ self.writer
+ }
+
+ #[inline]
+ fn write_u8(&mut self, major: u8, value: u8) -> Result<()> {
+ if value <= 0x17 {
+ self.writer.write_all(&[major << 5 | value])
+ } else {
+ let buf = [major << 5 | 24, value];
+ self.writer.write_all(&buf)
+ }
+ .map_err(|e| e.into())
+ }
+
+ #[inline]
+ fn write_u16(&mut self, major: u8, value: u16) -> Result<()> {
+ if value <= u16::from(u8::max_value()) {
+ self.write_u8(major, value as u8)
+ } else {
+ let mut buf = [major << 5 | 25, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&value.to_be_bytes());
+ self.writer.write_all(&buf).map_err(|e| e.into())
+ }
+ }
+
+ #[inline]
+ fn write_u32(&mut self, major: u8, value: u32) -> Result<()> {
+ if value <= u32::from(u16::max_value()) {
+ self.write_u16(major, value as u16)
+ } else {
+ let mut buf = [major << 5 | 26, 0, 0, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&value.to_be_bytes());
+ self.writer.write_all(&buf).map_err(|e| e.into())
+ }
+ }
+
+ #[inline]
+ fn write_u64(&mut self, major: u8, value: u64) -> Result<()> {
+ if value <= u64::from(u32::max_value()) {
+ self.write_u32(major, value as u32)
+ } else {
+ let mut buf = [major << 5 | 27, 0, 0, 0, 0, 0, 0, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&value.to_be_bytes());
+ self.writer.write_all(&buf).map_err(|e| e.into())
+ }
+ }
+
+ #[inline]
+ fn serialize_collection<'a>(
+ &'a mut self,
+ major: u8,
+ len: Option<usize>,
+ ) -> Result<CollectionSerializer<'a, W>> {
+ let needs_eof = match len {
+ Some(len) => {
+ self.write_u64(major, len as u64)?;
+ false
+ }
+ None => {
+ self.writer
+ .write_all(&[major << 5 | 31])
+ .map_err(|e| e.into())?;
+ true
+ }
+ };
+
+ Ok(CollectionSerializer {
+ ser: self,
+ needs_eof,
+ })
+ }
+}
+
+impl<'a, W> ser::Serializer for &'a mut Serializer<W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ type SerializeSeq = CollectionSerializer<'a, W>;
+ type SerializeTuple = &'a mut Serializer<W>;
+ type SerializeTupleStruct = &'a mut Serializer<W>;
+ type SerializeTupleVariant = &'a mut Serializer<W>;
+ type SerializeMap = CollectionSerializer<'a, W>;
+ type SerializeStruct = StructSerializer<'a, W>;
+ type SerializeStructVariant = StructSerializer<'a, W>;
+
+ #[inline]
+ fn serialize_bool(self, value: bool) -> Result<()> {
+ let value = if value { 0xf5 } else { 0xf4 };
+ self.writer.write_all(&[value]).map_err(|e| e.into())
+ }
+
+ #[inline]
+ fn serialize_i8(self, value: i8) -> Result<()> {
+ if value < 0 {
+ self.write_u8(1, -(value + 1) as u8)
+ } else {
+ self.write_u8(0, value as u8)
+ }
+ }
+
+ #[inline]
+ fn serialize_i16(self, value: i16) -> Result<()> {
+ if value < 0 {
+ self.write_u16(1, -(value + 1) as u16)
+ } else {
+ self.write_u16(0, value as u16)
+ }
+ }
+
+ #[inline]
+ fn serialize_i32(self, value: i32) -> Result<()> {
+ if value < 0 {
+ self.write_u32(1, -(value + 1) as u32)
+ } else {
+ self.write_u32(0, value as u32)
+ }
+ }
+
+ #[inline]
+ fn serialize_i64(self, value: i64) -> Result<()> {
+ if value < 0 {
+ self.write_u64(1, -(value + 1) as u64)
+ } else {
+ self.write_u64(0, value as u64)
+ }
+ }
+
+ #[inline]
+ fn serialize_i128(self, value: i128) -> Result<()> {
+ if value < 0 {
+ if -(value + 1) > i128::from(u64::max_value()) {
+ return Err(Error::message("The number can't be stored in CBOR"));
+ }
+ self.write_u64(1, -(value + 1) as u64)
+ } else {
+ if value > i128::from(u64::max_value()) {
+ return Err(Error::message("The number can't be stored in CBOR"));
+ }
+ self.write_u64(0, value as u64)
+ }
+ }
+
+ #[inline]
+ fn serialize_u8(self, value: u8) -> Result<()> {
+ self.write_u8(0, value)
+ }
+
+ #[inline]
+ fn serialize_u16(self, value: u16) -> Result<()> {
+ self.write_u16(0, value)
+ }
+
+ #[inline]
+ fn serialize_u32(self, value: u32) -> Result<()> {
+ self.write_u32(0, value)
+ }
+
+ #[inline]
+ fn serialize_u64(self, value: u64) -> Result<()> {
+ self.write_u64(0, value)
+ }
+
+ #[inline]
+ fn serialize_u128(self, value: u128) -> Result<()> {
+ if value > u128::from(u64::max_value()) {
+ return Err(Error::message("The number can't be stored in CBOR"));
+ }
+ self.write_u64(0, value as u64)
+ }
+
+ #[inline]
+ #[allow(clippy::float_cmp)]
+ fn serialize_f32(self, value: f32) -> Result<()> {
+ if value.is_infinite() {
+ if value.is_sign_positive() {
+ self.writer.write_all(&[0xf9, 0x7c, 0x00])
+ } else {
+ self.writer.write_all(&[0xf9, 0xfc, 0x00])
+ }
+ } else if value.is_nan() {
+ self.writer.write_all(&[0xf9, 0x7e, 0x00])
+ } else if f32::from(f16::from_f32(value)) == value {
+ let mut buf = [0xf9, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&f16::from_f32(value).to_bits().to_be_bytes());
+ self.writer.write_all(&buf)
+ } else {
+ let mut buf = [0xfa, 0, 0, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&value.to_bits().to_be_bytes());
+ self.writer.write_all(&buf)
+ }
+ .map_err(|e| e.into())
+ }
+
+ #[inline]
+ #[allow(clippy::float_cmp)]
+ fn serialize_f64(self, value: f64) -> Result<()> {
+ if !value.is_finite() || f64::from(value as f32) == value {
+ self.serialize_f32(value as f32)
+ } else {
+ let mut buf = [0xfb, 0, 0, 0, 0, 0, 0, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&value.to_bits().to_be_bytes());
+ self.writer.write_all(&buf).map_err(|e| e.into())
+ }
+ }
+
+ #[inline]
+ fn serialize_char(self, value: char) -> Result<()> {
+ // A char encoded as UTF-8 takes 4 bytes at most.
+ let mut buf = [0; 4];
+ self.serialize_str(value.encode_utf8(&mut buf))
+ }
+
+ #[inline]
+ fn serialize_str(self, value: &str) -> Result<()> {
+ self.write_u64(3, value.len() as u64)?;
+ self.writer
+ .write_all(value.as_bytes())
+ .map_err(|e| e.into())
+ }
+
+ #[inline]
+ fn serialize_bytes(self, value: &[u8]) -> Result<()> {
+ self.write_u64(2, value.len() as u64)?;
+ self.writer.write_all(value).map_err(|e| e.into())
+ }
+
+ #[inline]
+ fn serialize_unit(self) -> Result<()> {
+ self.serialize_none()
+ }
+
+ #[inline]
+ fn serialize_some<T>(self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(self)
+ }
+
+ #[inline]
+ fn serialize_none(self) -> Result<()> {
+ self.writer.write_all(&[0xf6]).map_err(|e| e.into())
+ }
+
+ #[inline]
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ ) -> Result<()> {
+ if self.packed {
+ self.serialize_u32(variant_index)
+ } else {
+ self.serialize_str(variant)
+ }
+ }
+
+ #[inline]
+ fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ if name == CBOR_NEWTYPE_NAME {
+ for tag in get_tag().into_iter() {
+ self.write_u64(6, tag)?;
+ }
+ }
+ value.serialize(self)
+ }
+
+ #[inline]
+ fn serialize_newtype_variant<T>(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ if self.enum_as_map {
+ self.write_u64(5, 1u64)?;
+ variant.serialize(&mut *self)?;
+ } else {
+ self.writer.write_all(&[4 << 5 | 2]).map_err(|e| e.into())?;
+ self.serialize_unit_variant(name, variant_index, variant)?;
+ }
+ value.serialize(self)
+ }
+
+ #[inline]
+ fn serialize_seq(self, len: Option<usize>) -> Result<CollectionSerializer<'a, W>> {
+ self.serialize_collection(4, len)
+ }
+
+ #[inline]
+ fn serialize_tuple(self, len: usize) -> Result<&'a mut Serializer<W>> {
+ self.write_u64(4, len as u64)?;
+ Ok(self)
+ }
+
+ #[inline]
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<&'a mut Serializer<W>> {
+ self.serialize_tuple(len)
+ }
+
+ #[inline]
+ fn serialize_tuple_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<&'a mut Serializer<W>> {
+ if self.enum_as_map {
+ self.write_u64(5, 1u64)?;
+ variant.serialize(&mut *self)?;
+ self.serialize_tuple(len)
+ } else {
+ self.write_u64(4, (len + 1) as u64)?;
+ self.serialize_unit_variant(name, variant_index, variant)?;
+ Ok(self)
+ }
+ }
+
+ #[inline]
+ fn serialize_map(self, len: Option<usize>) -> Result<CollectionSerializer<'a, W>> {
+ self.serialize_collection(5, len)
+ }
+
+ #[cfg(not(feature = "std"))]
+ fn collect_str<T: ?Sized>(self, value: &T) -> Result<()>
+ where
+ T: core::fmt::Display,
+ {
+ use crate::write::FmtWrite;
+ use core::fmt::Write;
+
+ let mut w = FmtWrite::new(&mut self.writer);
+ write!(w, "{}", value)?;
+ Ok(())
+ }
+
+ #[inline]
+ fn serialize_struct(self, _name: &'static str, len: usize) -> Result<StructSerializer<'a, W>> {
+ self.write_u64(5, len as u64)?;
+ Ok(StructSerializer { ser: self, idx: 0 })
+ }
+
+ #[inline]
+ fn serialize_struct_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<StructSerializer<'a, W>> {
+ if self.enum_as_map {
+ self.write_u64(5, 1u64)?;
+ } else {
+ self.writer.write_all(&[4 << 5 | 2]).map_err(|e| e.into())?;
+ }
+ self.serialize_unit_variant(name, variant_index, variant)?;
+ self.serialize_struct(name, len)
+ }
+
+ #[inline]
+ fn is_human_readable(&self) -> bool {
+ false
+ }
+}
+
+impl<'a, W> ser::SerializeTuple for &'a mut Serializer<W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(&mut **self)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ Ok(())
+ }
+}
+
+impl<'a, W> ser::SerializeTupleStruct for &'a mut Serializer<W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(&mut **self)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ Ok(())
+ }
+}
+
+impl<'a, W> ser::SerializeTupleVariant for &'a mut Serializer<W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(&mut **self)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ Ok(())
+ }
+}
+
+#[doc(hidden)]
+pub struct StructSerializer<'a, W> {
+ ser: &'a mut Serializer<W>,
+ idx: u32,
+}
+
+impl<'a, W> StructSerializer<'a, W>
+where
+ W: Write,
+{
+ #[inline]
+ fn serialize_field_inner<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ if self.ser.packed {
+ self.idx.serialize(&mut *self.ser)?;
+ } else {
+ key.serialize(&mut *self.ser)?;
+ }
+ value.serialize(&mut *self.ser)?;
+ self.idx += 1;
+ Ok(())
+ }
+
+ #[inline]
+ fn skip_field_inner(&mut self, _: &'static str) -> Result<()> {
+ self.idx += 1;
+ Ok(())
+ }
+
+ #[inline]
+ fn end_inner(self) -> Result<()> {
+ Ok(())
+ }
+}
+
+impl<'a, W> ser::SerializeStruct for StructSerializer<'a, W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.serialize_field_inner(key, value)
+ }
+
+ #[inline]
+ fn skip_field(&mut self, key: &'static str) -> Result<()> {
+ self.skip_field_inner(key)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ self.end_inner()
+ }
+}
+
+impl<'a, W> ser::SerializeStructVariant for StructSerializer<'a, W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.serialize_field_inner(key, value)
+ }
+
+ #[inline]
+ fn skip_field(&mut self, key: &'static str) -> Result<()> {
+ self.skip_field_inner(key)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ self.end_inner()
+ }
+}
+
+#[doc(hidden)]
+pub struct CollectionSerializer<'a, W> {
+ ser: &'a mut Serializer<W>,
+ needs_eof: bool,
+}
+
+impl<'a, W> CollectionSerializer<'a, W>
+where
+ W: Write,
+{
+ #[inline]
+ fn end_inner(self) -> Result<()> {
+ if self.needs_eof {
+ self.ser.writer.write_all(&[0xff]).map_err(|e| e.into())
+ } else {
+ Ok(())
+ }
+ }
+}
+
+impl<'a, W> ser::SerializeSeq for CollectionSerializer<'a, W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(&mut *self.ser)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ self.end_inner()
+ }
+}
+
+impl<'a, W> ser::SerializeMap for CollectionSerializer<'a, W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_key<T>(&mut self, key: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ key.serialize(&mut *self.ser)
+ }
+
+ #[inline]
+ fn serialize_value<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(&mut *self.ser)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ self.end_inner()
+ }
+}
diff --git a/third_party/rust/serde_cbor/src/tags.rs b/third_party/rust/serde_cbor/src/tags.rs
new file mode 100644
index 0000000000..8adccb8ea8
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/tags.rs
@@ -0,0 +1,220 @@
+//! Support for cbor tags
+use core::fmt;
+use core::marker::PhantomData;
+use serde::de::{
+ Deserialize, Deserializer, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, Visitor,
+};
+use serde::forward_to_deserialize_any;
+use serde::ser::{Serialize, Serializer};
+
+/// signals that a newtype is from a CBOR tag
+pub(crate) const CBOR_NEWTYPE_NAME: &str = "\0cbor_tag";
+
+/// A value that is optionally tagged with a cbor tag
+///
+/// this only serves as an intermediate helper for tag serialization or deserialization
+pub struct Tagged<T> {
+ /// cbor tag
+ pub tag: Option<u64>,
+ /// value
+ pub value: T,
+}
+
+impl<T> Tagged<T> {
+ /// Create a new tagged value
+ pub fn new(tag: Option<u64>, value: T) -> Self {
+ Self { tag, value }
+ }
+}
+
+impl<T: Serialize> Serialize for Tagged<T> {
+ fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
+ set_tag(self.tag);
+ let r = s.serialize_newtype_struct(CBOR_NEWTYPE_NAME, &self.value);
+ set_tag(None);
+ r
+ }
+}
+
+fn untagged<T>(value: T) -> Tagged<T> {
+ Tagged::new(None, value)
+}
+
+macro_rules! delegate {
+ ($name: ident, $type: ty) => {
+ fn $name<E: serde::de::Error>(self, v: $type) -> Result<Self::Value, E> {
+ T::deserialize(v.into_deserializer()).map(untagged)
+ }
+ };
+}
+
+struct EnumDeserializer<A>(A);
+
+impl<'de, A> Deserializer<'de> for EnumDeserializer<A>
+where
+ A: EnumAccess<'de>,
+{
+ type Error = A::Error;
+
+ fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
+ visitor.visit_enum(self.0)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+struct NoneDeserializer<E>(PhantomData<E>);
+
+impl<'de, E> Deserializer<'de> for NoneDeserializer<E>
+where
+ E: serde::de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
+ visitor.visit_none()
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+struct BytesDeserializer<'a, E>(&'a [u8], PhantomData<E>);
+
+impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
+where
+ E: serde::de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
+ visitor.visit_bytes(self.0)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+/// A visitor that intercepts *just* visit_newtype_struct and passes through everything else.
+struct MaybeTaggedVisitor<T>(PhantomData<T>);
+
+impl<'de, T: Deserialize<'de>> Visitor<'de> for MaybeTaggedVisitor<T> {
+ type Value = Tagged<T>;
+
+ fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.write_str("a cbor tag newtype")
+ }
+
+ delegate!(visit_bool, bool);
+
+ delegate!(visit_i8, i8);
+ delegate!(visit_i16, i16);
+ delegate!(visit_i32, i32);
+ delegate!(visit_i64, i64);
+
+ delegate!(visit_u8, u8);
+ delegate!(visit_u16, u16);
+ delegate!(visit_u32, u32);
+ delegate!(visit_u64, u64);
+
+ delegate!(visit_f32, f32);
+ delegate!(visit_f64, f64);
+
+ delegate!(visit_char, char);
+ delegate!(visit_str, &str);
+ delegate!(visit_borrowed_str, &'de str);
+
+ #[cfg(feature = "std")]
+ delegate!(visit_byte_buf, Vec<u8>);
+
+ #[cfg(feature = "std")]
+ delegate!(visit_string, String);
+
+ fn visit_bytes<E: serde::de::Error>(self, value: &[u8]) -> Result<Self::Value, E> {
+ T::deserialize(BytesDeserializer(value, PhantomData)).map(untagged)
+ }
+
+ fn visit_borrowed_bytes<E: serde::de::Error>(self, value: &'de [u8]) -> Result<Self::Value, E> {
+ T::deserialize(serde::de::value::BorrowedBytesDeserializer::new(value)).map(untagged)
+ }
+
+ fn visit_unit<E: serde::de::Error>(self) -> Result<Self::Value, E> {
+ T::deserialize(().into_deserializer()).map(untagged)
+ }
+
+ fn visit_none<E: serde::de::Error>(self) -> Result<Self::Value, E> {
+ T::deserialize(NoneDeserializer(PhantomData)).map(untagged)
+ }
+
+ fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
+ T::deserialize(deserializer).map(untagged)
+ }
+
+ fn visit_seq<A: SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
+ T::deserialize(serde::de::value::SeqAccessDeserializer::new(seq)).map(untagged)
+ }
+
+ fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
+ T::deserialize(serde::de::value::MapAccessDeserializer::new(map)).map(untagged)
+ }
+
+ fn visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
+ T::deserialize(EnumDeserializer(data)).map(untagged)
+ }
+
+ fn visit_newtype_struct<D: serde::Deserializer<'de>>(
+ self,
+ deserializer: D,
+ ) -> Result<Self::Value, D::Error> {
+ let t = get_tag();
+ T::deserialize(deserializer).map(|v| Tagged::new(t, v))
+ }
+}
+
+impl<'de, T: serde::de::Deserialize<'de>> serde::de::Deserialize<'de> for Tagged<T> {
+ fn deserialize<D: serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+ deserializer.deserialize_any(MaybeTaggedVisitor::<T>(PhantomData))
+ }
+}
+
+/// function to get the current cbor tag
+///
+/// The only place where it makes sense to call this function is within visit_newtype_struct of a serde visitor.
+/// This is a low level API. In most cases it is preferable to use Tagged
+pub fn current_cbor_tag() -> Option<u64> {
+ get_tag()
+}
+
+#[cfg(feature = "tags")]
+pub(crate) fn set_tag(value: Option<u64>) {
+ CBOR_TAG.with(|f| *f.borrow_mut() = value);
+}
+
+#[cfg(feature = "tags")]
+pub(crate) fn get_tag() -> Option<u64> {
+ CBOR_TAG.with(|f| *f.borrow())
+}
+
+#[cfg(not(feature = "tags"))]
+pub(crate) fn set_tag(_value: Option<u64>) {}
+
+#[cfg(not(feature = "tags"))]
+pub(crate) fn get_tag() -> Option<u64> {
+ None
+}
+
+#[cfg(feature = "tags")]
+use std::cell::RefCell;
+
+#[cfg(feature = "tags")]
+thread_local!(static CBOR_TAG: RefCell<Option<u64>> = RefCell::new(None));
diff --git a/third_party/rust/serde_cbor/src/value/de.rs b/third_party/rust/serde_cbor/src/value/de.rs
new file mode 100644
index 0000000000..f5bdbb7467
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/value/de.rs
@@ -0,0 +1,166 @@
+use std::collections::BTreeMap;
+use std::fmt;
+
+use crate::value::Value;
+use serde::de;
+
+impl<'de> de::Deserialize<'de> for Value {
+ #[inline]
+ fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ struct ValueVisitor;
+
+ impl<'de> de::Visitor<'de> for ValueVisitor {
+ type Value = Value;
+
+ fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.write_str("any valid CBOR value")
+ }
+
+ #[inline]
+ fn visit_str<E>(self, value: &str) -> Result<Value, E>
+ where
+ E: de::Error,
+ {
+ self.visit_string(String::from(value))
+ }
+
+ #[inline]
+ fn visit_string<E>(self, value: String) -> Result<Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Text(value))
+ }
+ #[inline]
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ self.visit_byte_buf(v.to_owned())
+ }
+
+ #[inline]
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Bytes(v))
+ }
+
+ #[inline]
+ fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Integer(v.into()))
+ }
+
+ #[inline]
+ fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Integer(v.into()))
+ }
+
+ #[inline]
+ fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Integer(v))
+ }
+
+ #[inline]
+ fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Bool(v))
+ }
+
+ #[inline]
+ fn visit_none<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ self.visit_unit()
+ }
+
+ #[inline]
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Null)
+ }
+
+ #[inline]
+ fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: de::SeqAccess<'de>,
+ {
+ let mut vec = Vec::new();
+
+ while let Some(elem) = visitor.next_element()? {
+ vec.push(elem);
+ }
+
+ Ok(Value::Array(vec))
+ }
+
+ #[inline]
+ fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
+ where
+ V: de::MapAccess<'de>,
+ {
+ let mut values = BTreeMap::new();
+
+ while let Some((key, value)) = visitor.next_entry()? {
+ values.insert(key, value);
+ }
+
+ Ok(Value::Map(values))
+ }
+
+ #[inline]
+ fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Float(v))
+ }
+
+ fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let tag = crate::tags::get_tag();
+ let inner = deserializer.deserialize_any(self);
+ match tag {
+ Some(tag) => inner.map(|v| Value::Tag(tag, Box::new(v))),
+ None => inner,
+ }
+ }
+ }
+
+ deserializer.deserialize_any(ValueVisitor)
+ }
+}
+
+/// Convert a `serde_cbor::Value` into a type `T`
+#[allow(clippy::needless_pass_by_value)]
+pub fn from_value<T>(value: Value) -> Result<T, crate::error::Error>
+where
+ T: de::DeserializeOwned,
+{
+ // TODO implement in a way that doesn't require
+ // roundtrip through buffer (i.e. by implementing
+ // `serde::de::Deserializer` for `Value` and then doing
+ // `T::deserialize(value)`).
+ let buf = crate::to_vec(&value)?;
+ crate::from_slice(buf.as_slice())
+}
diff --git a/third_party/rust/serde_cbor/src/value/mod.rs b/third_party/rust/serde_cbor/src/value/mod.rs
new file mode 100644
index 0000000000..7bd2255314
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/value/mod.rs
@@ -0,0 +1,156 @@
+//! CBOR values, keys and serialization routines.
+
+mod de;
+mod ser;
+
+use std::cmp::{Ord, Ordering, PartialOrd};
+use std::collections::BTreeMap;
+
+#[doc(inline)]
+pub use self::de::from_value;
+#[doc(inline)]
+pub use self::ser::to_value;
+
+/// The `Value` enum, a loosely typed way of representing any valid CBOR value.
+///
+/// Maps are sorted according to the canonical ordering
+/// described in [RFC 7049 bis].
+/// Therefore values are unambiguously serialized
+/// to a canonical form of CBOR from the same RFC.
+///
+/// [RFC 7049 bis]: https://tools.ietf.org/html/draft-ietf-cbor-7049bis-04#section-2
+#[derive(Clone, Debug)]
+pub enum Value {
+ /// Represents the absence of a value or the value undefined.
+ Null,
+ /// Represents a boolean value.
+ Bool(bool),
+ /// Integer CBOR numbers.
+ ///
+ /// The biggest value that can be represented is 2^64 - 1.
+ /// While the smallest value is -2^64.
+ /// Values outside this range can't be serialized
+ /// and will cause an error.
+ Integer(i128),
+ /// Represents a floating point value.
+ Float(f64),
+ /// Represents a byte string.
+ Bytes(Vec<u8>),
+ /// Represents an UTF-8 encoded string.
+ Text(String),
+ /// Represents an array of values.
+ Array(Vec<Value>),
+ /// Represents a map.
+ ///
+ /// Maps are also called tables, dictionaries, hashes, or objects (in JSON).
+ /// While any value can be used as a CBOR key
+ /// it is better to use only one type of key in a map
+ /// to avoid ambiguity.
+ /// If floating point values are used as keys they are compared bit-by-bit for equality.
+ /// If arrays or maps are used as keys the comparisons
+ /// to establish canonical order may be slow and therefore insertion
+ /// and retrieval of values will be slow too.
+ Map(BTreeMap<Value, Value>),
+ /// Represents a tagged value
+ Tag(u64, Box<Value>),
+ // The hidden variant allows the enum to be extended
+ // with variants for tags and simple values.
+ #[doc(hidden)]
+ __Hidden,
+}
+
+impl PartialEq for Value {
+ fn eq(&self, other: &Value) -> bool {
+ self.cmp(other) == Ordering::Equal
+ }
+}
+
+impl Eq for Value {}
+
+impl PartialOrd for Value {
+ fn partial_cmp(&self, other: &Value) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for Value {
+ fn cmp(&self, other: &Value) -> Ordering {
+ // Determine the canonical order of two values:
+ // 1. Smaller major type sorts first.
+ // 2. Shorter sequence sorts first.
+ // 3. Compare integers by magnitude.
+ // 4. Compare byte and text sequences lexically.
+ // 5. Compare the serializations of both types. (expensive)
+ use self::Value::*;
+ if self.major_type() != other.major_type() {
+ return self.major_type().cmp(&other.major_type());
+ }
+ match (self, other) {
+ (Integer(a), Integer(b)) => a.abs().cmp(&b.abs()),
+ (Bytes(a), Bytes(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+ (Text(a), Text(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+ (Array(a), Array(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+ (Map(a), Map(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+ (Bytes(a), Bytes(b)) => a.cmp(b),
+ (Text(a), Text(b)) => a.cmp(b),
+ (a, b) => {
+ let a = crate::to_vec(a).expect("self is serializable");
+ let b = crate::to_vec(b).expect("other is serializable");
+ a.cmp(&b)
+ }
+ }
+ }
+}
+
+macro_rules! impl_from {
+ ($variant:path, $for_type:ty) => {
+ impl From<$for_type> for Value {
+ fn from(v: $for_type) -> Value {
+ $variant(v.into())
+ }
+ }
+ };
+}
+
+impl_from!(Value::Bool, bool);
+impl_from!(Value::Integer, i8);
+impl_from!(Value::Integer, i16);
+impl_from!(Value::Integer, i32);
+impl_from!(Value::Integer, i64);
+// i128 omitted because not all numbers fit in CBOR serialization
+impl_from!(Value::Integer, u8);
+impl_from!(Value::Integer, u16);
+impl_from!(Value::Integer, u32);
+impl_from!(Value::Integer, u64);
+// u128 omitted because not all numbers fit in CBOR serialization
+impl_from!(Value::Float, f32);
+impl_from!(Value::Float, f64);
+impl_from!(Value::Bytes, Vec<u8>);
+impl_from!(Value::Text, String);
+// TODO: figure out if these impls should be more generic or removed.
+impl_from!(Value::Array, Vec<Value>);
+impl_from!(Value::Map, BTreeMap<Value, Value>);
+
+impl Value {
+ fn major_type(&self) -> u8 {
+ use self::Value::*;
+ match self {
+ Null => 7,
+ Bool(_) => 7,
+ Integer(v) => {
+ if *v >= 0 {
+ 0
+ } else {
+ 1
+ }
+ }
+ Tag(_, _) => 6,
+ Float(_) => 7,
+ Bytes(_) => 2,
+ Text(_) => 3,
+ Array(_) => 4,
+ Map(_) => 5,
+ __Hidden => unreachable!(),
+ }
+ }
+}
diff --git a/third_party/rust/serde_cbor/src/value/ser.rs b/third_party/rust/serde_cbor/src/value/ser.rs
new file mode 100644
index 0000000000..347aae9601
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/value/ser.rs
@@ -0,0 +1,443 @@
+// Copyright 2017 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::collections::BTreeMap;
+
+use crate::error::Error;
+use serde::{self, Serialize};
+
+use crate::tags::Tagged;
+use crate::value::Value;
+
+impl serde::Serialize for Value {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ match *self {
+ Value::Integer(v) => serializer.serialize_i128(v),
+ Value::Bytes(ref v) => serializer.serialize_bytes(&v),
+ Value::Text(ref v) => serializer.serialize_str(&v),
+ Value::Array(ref v) => v.serialize(serializer),
+ Value::Map(ref v) => v.serialize(serializer),
+ Value::Tag(tag, ref v) => Tagged::new(Some(tag), v).serialize(serializer),
+ Value::Float(v) => serializer.serialize_f64(v),
+ Value::Bool(v) => serializer.serialize_bool(v),
+ Value::Null => serializer.serialize_unit(),
+ Value::__Hidden => unreachable!(),
+ }
+ }
+}
+
+struct Serializer;
+
+impl serde::Serializer for Serializer {
+ type Ok = Value;
+ type Error = Error;
+
+ type SerializeSeq = SerializeVec;
+ type SerializeTuple = SerializeVec;
+ type SerializeTupleStruct = SerializeVec;
+ type SerializeTupleVariant = SerializeTupleVariant;
+ type SerializeMap = SerializeMap;
+ type SerializeStruct = SerializeMap;
+ type SerializeStructVariant = SerializeStructVariant;
+
+ #[inline]
+ fn serialize_bool(self, value: bool) -> Result<Value, Error> {
+ Ok(Value::Bool(value))
+ }
+
+ #[inline]
+ fn serialize_i8(self, value: i8) -> Result<Value, Error> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_i16(self, value: i16) -> Result<Value, Error> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_i32(self, value: i32) -> Result<Value, Error> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_i64(self, value: i64) -> Result<Value, Error> {
+ self.serialize_i128(i128::from(value))
+ }
+
+ fn serialize_i128(self, value: i128) -> Result<Value, Error> {
+ Ok(Value::Integer(value))
+ }
+
+ #[inline]
+ fn serialize_u8(self, value: u8) -> Result<Value, Error> {
+ self.serialize_u64(u64::from(value))
+ }
+
+ #[inline]
+ fn serialize_u16(self, value: u16) -> Result<Value, Error> {
+ self.serialize_u64(u64::from(value))
+ }
+
+ #[inline]
+ fn serialize_u32(self, value: u32) -> Result<Value, Error> {
+ self.serialize_u64(u64::from(value))
+ }
+
+ #[inline]
+ fn serialize_u64(self, value: u64) -> Result<Value, Error> {
+ Ok(Value::Integer(value.into()))
+ }
+
+ #[inline]
+ fn serialize_f32(self, value: f32) -> Result<Value, Error> {
+ self.serialize_f64(f64::from(value))
+ }
+
+ #[inline]
+ fn serialize_f64(self, value: f64) -> Result<Value, Error> {
+ Ok(Value::Float(value))
+ }
+
+ #[inline]
+ fn serialize_char(self, value: char) -> Result<Value, Error> {
+ let mut s = String::new();
+ s.push(value);
+ self.serialize_str(&s)
+ }
+
+ #[inline]
+ fn serialize_str(self, value: &str) -> Result<Value, Error> {
+ Ok(Value::Text(value.to_owned()))
+ }
+
+ fn serialize_bytes(self, value: &[u8]) -> Result<Value, Error> {
+ Ok(Value::Bytes(value.to_vec()))
+ }
+
+ #[inline]
+ fn serialize_unit(self) -> Result<Value, Error> {
+ Ok(Value::Null)
+ }
+
+ #[inline]
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, Error> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Value, Error> {
+ self.serialize_str(variant)
+ }
+
+ #[inline]
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ _name: &'static str,
+ value: &T,
+ ) -> Result<Value, Error>
+ where
+ T: Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Value, Error>
+ where
+ T: Serialize,
+ {
+ let mut values = BTreeMap::new();
+ values.insert(Value::from(variant.to_owned()), to_value(&value)?);
+ Ok(Value::Map(values))
+ }
+
+ #[inline]
+ fn serialize_none(self) -> Result<Value, Error> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Value, Error>
+ where
+ T: Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
+ Ok(SerializeVec {
+ vec: Vec::with_capacity(len.unwrap_or(0)),
+ })
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Error> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Error> {
+ self.serialize_tuple(len)
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Error> {
+ Ok(SerializeTupleVariant {
+ name: String::from(variant),
+ vec: Vec::with_capacity(len),
+ })
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Error> {
+ Ok(SerializeMap {
+ map: BTreeMap::new(),
+ next_key: None,
+ })
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStruct, Error> {
+ self.serialize_map(Some(len))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant, Error> {
+ Ok(SerializeStructVariant {
+ name: String::from(variant),
+ map: BTreeMap::new(),
+ })
+ }
+
+ #[inline]
+ fn is_human_readable(&self) -> bool {
+ false
+ }
+}
+
+pub struct SerializeVec {
+ vec: Vec<Value>,
+}
+
+pub struct SerializeTupleVariant {
+ name: String,
+ vec: Vec<Value>,
+}
+
+pub struct SerializeMap {
+ map: BTreeMap<Value, Value>,
+ next_key: Option<Value>,
+}
+
+pub struct SerializeStructVariant {
+ name: String,
+ map: BTreeMap<Value, Value>,
+}
+
+impl serde::ser::SerializeSeq for SerializeVec {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ self.vec.push(to_value(&value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ Ok(Value::Array(self.vec))
+ }
+}
+
+impl serde::ser::SerializeTuple for SerializeVec {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ serde::ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ serde::ser::SerializeSeq::end(self)
+ }
+}
+
+impl serde::ser::SerializeTupleStruct for SerializeVec {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ serde::ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ serde::ser::SerializeSeq::end(self)
+ }
+}
+
+impl serde::ser::SerializeTupleVariant for SerializeTupleVariant {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ self.vec.push(to_value(&value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ let mut object = BTreeMap::new();
+
+ object.insert(Value::from(self.name), Value::Array(self.vec));
+
+ Ok(Value::Map(object))
+ }
+}
+
+impl serde::ser::SerializeMap for SerializeMap {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ self.next_key = Some(to_value(&key)?);
+ Ok(())
+ }
+
+ fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ let key = self.next_key.take();
+ // Panic because this indicates a bug in the program rather than an
+ // expected failure.
+ let key = key.expect("serialize_value called before serialize_key");
+ self.map.insert(key, to_value(&value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ Ok(Value::Map(self.map))
+ }
+}
+
+impl serde::ser::SerializeStruct for SerializeMap {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ serde::ser::SerializeMap::serialize_key(self, key)?;
+ serde::ser::SerializeMap::serialize_value(self, value)
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ serde::ser::SerializeMap::end(self)
+ }
+}
+
+impl serde::ser::SerializeStructVariant for SerializeStructVariant {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ self.map
+ .insert(Value::from(String::from(key)), to_value(&value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ let mut object = BTreeMap::new();
+
+ object.insert(Value::from(self.name), Value::Map(self.map));
+
+ Ok(Value::Map(object))
+ }
+}
+
+/// Convert a `T` into `serde_cbor::Value` which is an enum that can represent
+/// any valid CBOR data.
+///
+/// ```rust
+/// extern crate serde;
+///
+/// #[macro_use]
+/// extern crate serde_derive;
+/// extern crate serde_cbor;
+///
+/// use std::error::Error;
+///
+/// #[derive(Serialize)]
+/// struct User {
+/// fingerprint: String,
+/// location: String,
+/// }
+///
+/// fn main() {
+/// let u = User {
+/// fingerprint: "0xF9BA143B95FF6D82".to_owned(),
+/// location: "Menlo Park, CA".to_owned(),
+/// };
+///
+/// let v = serde_cbor::value::to_value(u).unwrap();
+/// }
+/// ```
+#[allow(clippy::needless_pass_by_value)]
+// Taking by value is more friendly to iterator adapters, option and result
+pub fn to_value<T>(value: T) -> Result<Value, Error>
+where
+ T: Serialize,
+{
+ value.serialize(Serializer)
+}
diff --git a/third_party/rust/serde_cbor/src/write.rs b/third_party/rust/serde_cbor/src/write.rs
new file mode 100644
index 0000000000..94c326ef96
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/write.rs
@@ -0,0 +1,175 @@
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+#[cfg(not(feature = "std"))]
+use core::fmt;
+#[cfg(feature = "std")]
+use std::io;
+
+use crate::error;
+
+#[cfg(not(feature = "unsealed_read_write"))]
+/// A sink for serialized CBOR.
+///
+/// This trait is similar to the [`Write`]() trait in the standard library,
+/// but has a smaller and more general API.
+///
+/// Any object implementing `std::io::Write`
+/// can be wrapped in an [`IoWrite`](../write/struct.IoWrite.html) that implements
+/// this trait for the underlying object.
+pub trait Write: private::Sealed {
+ /// The type of error returned when a write operation fails.
+ #[doc(hidden)]
+ type Error: Into<error::Error>;
+
+ /// Attempts to write an entire buffer into this write.
+ #[doc(hidden)]
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
+}
+
+#[cfg(feature = "unsealed_read_write")]
+/// A sink for serialized CBOR.
+///
+/// This trait is similar to the [`Write`]() trait in the standard library,
+/// but has a smaller and more general API.
+///
+/// Any object implementing `std::io::Write`
+/// can be wrapped in an [`IoWrite`](../write/struct.IoWrite.html) that implements
+/// this trait for the underlying object.
+///
+/// This trait is sealed by default, enabling the `unsealed_read_write` feature removes this bound
+/// to allow objects outside of this crate to implement this trait.
+pub trait Write {
+ /// The type of error returned when a write operation fails.
+ type Error: Into<error::Error>;
+
+ /// Attempts to write an entire buffer into this write.
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+mod private {
+ pub trait Sealed {}
+}
+
+impl<W> Write for &mut W
+where
+ W: Write,
+{
+ type Error = W::Error;
+
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
+ (*self).write_all(buf)
+ }
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+impl<W> private::Sealed for &mut W where W: Write {}
+
+#[cfg(feature = "std")]
+/// A wrapper for types that implement
+/// [`std::io::Write`](https://doc.rust-lang.org/std/io/trait.Write.html) to implement the local
+/// [`Write`](trait.Write.html) trait.
+#[derive(Debug)]
+pub struct IoWrite<W>(W);
+
+#[cfg(feature = "std")]
+impl<W: io::Write> IoWrite<W> {
+ /// Wraps an `io::Write` writer to make it compatible with [`Write`](trait.Write.html)
+ pub fn new(w: W) -> IoWrite<W> {
+ IoWrite(w)
+ }
+}
+
+#[cfg(feature = "std")]
+impl<W: io::Write> Write for IoWrite<W> {
+ type Error = io::Error;
+
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
+ self.0.write_all(buf)
+ }
+}
+
+#[cfg(all(feature = "std", not(feature = "unsealed_read_write")))]
+impl<W> private::Sealed for IoWrite<W> where W: io::Write {}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl Write for Vec<u8> {
+ type Error = error::Error;
+
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
+ self.extend_from_slice(buf);
+ Ok(())
+ }
+}
+
+#[cfg(all(
+ any(feature = "std", feature = "alloc"),
+ not(feature = "unsealed_read_write")
+))]
+impl private::Sealed for Vec<u8> {}
+
+#[cfg(not(feature = "std"))]
+#[derive(Debug)]
+pub struct FmtWrite<'a, W: Write>(&'a mut W);
+
+#[cfg(not(feature = "std"))]
+impl<'a, W: Write> FmtWrite<'a, W> {
+ /// Wraps an `fmt::Write` writer to make it compatible with [`Write`](trait.Write.html)
+ pub fn new(w: &'a mut W) -> FmtWrite<'a, W> {
+ FmtWrite(w)
+ }
+}
+
+#[cfg(not(feature = "std"))]
+impl<'a, W: Write> fmt::Write for FmtWrite<'a, W> {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ self.0.write_all(s.as_bytes()).map_err(|_| fmt::Error)
+ }
+}
+
+#[cfg(all(not(feature = "std"), not(feature = "unsealed_read_write")))]
+impl<'a, W> private::Sealed for FmtWrite<'a, W> where W: Write {}
+
+/// Implements [`Write`](trait.Write.html) for mutable byte slices (`&mut [u8]`).
+///
+/// Returns an error if the value to serialize is too large to fit in the slice.
+#[derive(Debug)]
+pub struct SliceWrite<'a> {
+ slice: &'a mut [u8],
+ index: usize,
+}
+
+impl<'a> SliceWrite<'a> {
+ /// Wraps a mutable slice so it can be used as a `Write`.
+ pub fn new(slice: &'a mut [u8]) -> SliceWrite<'a> {
+ SliceWrite { slice, index: 0 }
+ }
+
+ /// Returns the number of bytes written to the underlying slice.
+ pub fn bytes_written(&self) -> usize {
+ self.index
+ }
+
+ /// Returns the underlying slice.
+ pub fn into_inner(self) -> &'a mut [u8] {
+ self.slice
+ }
+}
+
+impl<'a> Write for SliceWrite<'a> {
+ type Error = error::Error;
+
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
+ if self.slice.len() - self.index < buf.len() {
+ // This buffer will not fit in our slice
+ return Err(error::Error::scratch_too_small(self.index as u64));
+ }
+ let end = self.index + buf.len();
+ self.slice[self.index..end].copy_from_slice(buf);
+ self.index = end;
+ Ok(())
+ }
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+impl<'a> private::Sealed for SliceWrite<'a> {}