From facfa1b3d643ed19447e2028d00a54ba0e1d8aef Mon Sep 17 00:00:00 2001 From: SimonIT Date: Tue, 12 Mar 2024 16:39:44 +0100 Subject: [PATCH 01/11] Begin to remove alloc --- Cargo.toml | 5 +- src/de.rs | 236 +++++++++++++++++++++++++++----------------------- src/error.rs | 17 ++-- src/len.rs | 6 +- src/lib.rs | 6 +- src/result.rs | 2 +- src/se.rs | 8 +- src/types.rs | 67 +++++++------- src/value.rs | 107 +++++++++++------------ 9 files changed, 234 insertions(+), 220 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c7ba219..156de6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "2.4.0" authors = ["Nicolas Di Prima ", "Vincent Hanquez "] license = "MIT OR Apache-2.0" readme = "README.md" -categories = [ "parsing", "encoding" ] +categories = ["parsing", "encoding"] keywords = ["cbor", "binary", "format", "encoding"] repository = "https://github.com/primetype/cbor_event" homepage = "https://github.com/primetype/cbor_event#readme.md" @@ -12,5 +12,8 @@ description = """ The CBOR Event library. There are no dependencies, all platforms are supported and it is wasm compatible. """ +[features] +alloc = [] + [dev-dependencies] quickcheck = "0.7" diff --git a/src/de.rs b/src/de.rs index aa76fd0..fd7293c 100644 --- a/src/de.rs +++ b/src/de.rs @@ -1,23 +1,27 @@ //! CBOR deserialisation tooling +#[cfg(feature = "alloc")] use alloc::collections::BTreeMap; +#[cfg(feature = "alloc")] use alloc::string::String; +#[cfg(feature = "alloc")] +use alloc::string::ToString; +#[cfg(feature = "alloc")] use alloc::vec::Vec; -use alloc::{format, vec}; -use core::fmt::{Display, Formatter}; +use core::fmt::{Display, Formatter, Write}; use error::Error; use len::{Len, LenSz, StringLenSz, Sz}; use result::Result; use types::{Special, Type}; -pub trait Deserialize: Sized { +pub trait Deserialize<'a>: Sized { /// method to implement to deserialise an object from the given /// `Deserializer`. - fn deserialize(reader: &mut Deserializer) -> Result; + fn deserialize(reader: &mut Deserializer<'a>) -> Result<'a, Self>; } -impl Deserialize for u8 { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a> Deserialize<'a> for u8 { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { let n = raw.unsigned_integer()?; if n > u8::MAX as u64 { Err(Error::ExpectedU8) @@ -27,8 +31,8 @@ impl Deserialize for u8 { } } -impl Deserialize for u16 { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a> Deserialize<'a> for u16 { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { let n = raw.unsigned_integer()?; if n > u16::MAX as u64 { Err(Error::ExpectedU16) @@ -38,8 +42,8 @@ impl Deserialize for u16 { } } -impl Deserialize for u32 { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a> Deserialize<'a> for u32 { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { let n = raw.unsigned_integer()?; if n > u32::MAX as u64 { Err(Error::ExpectedU32) @@ -49,38 +53,40 @@ impl Deserialize for u32 { } } -impl Deserialize for u64 { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a> Deserialize<'a> for u64 { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { raw.unsigned_integer() } } -impl Deserialize for bool { - fn deserialize(raw: &mut Deserializer) -> Result { - raw.bool() +impl<'a> Deserialize<'a> for bool { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + raw.bool().cloned() } } -impl Deserialize for f32 { - fn deserialize(raw: &mut Deserializer) -> Result { - raw.float().map(|f| f as f32) +impl<'a> Deserialize<'a> for f32 { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + raw.float().map(|f| f.clone() as f32) } } -impl Deserialize for f64 { - fn deserialize(raw: &mut Deserializer) -> Result { - raw.float() +impl<'a> Deserialize<'a> for f64 { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + raw.float().cloned() } } -impl Deserialize for String { - fn deserialize(raw: &mut Deserializer) -> Result { - raw.text() +#[cfg(feature = "alloc")] +impl<'a> Deserialize<'a> for String { + fn deserialize(raw: &mut Deserializer) -> Result<'a, Self> { + raw.text().map(|s| s.to_string()) } } +#[cfg(feature = "alloc")] impl Deserialize for Vec { - fn deserialize(raw: &mut Deserializer) -> Result { + fn deserialize(raw: &mut Deserializer) -> Result<'a, Self> { let mut vec = Vec::new(); raw.array_with(|raw| { vec.push(Deserialize::deserialize(raw)?); @@ -89,8 +95,9 @@ impl Deserialize for Vec { Ok(vec) } } +#[cfg(feature = "alloc")] impl Deserialize for BTreeMap { - fn deserialize(raw: &mut Deserializer) -> Result { + fn deserialize(raw: &mut Deserializer) -> Result<'a, Self> { let mut vec = BTreeMap::new(); raw.map_with(|raw| { let k = Deserialize::deserialize(raw)?; @@ -102,15 +109,16 @@ impl Deserialize for BTreeMap { } } -impl Deserialize for Option { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a, T: Deserialize<'a>> Deserialize<'a> for Option { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { match raw.array()? { Len::Len(0) => Ok(None), Len::Len(1) => Ok(Some(raw.deserialize()?)), - len => Err(Error::CustomError(format!( - "Invalid Option: received array of {:?} elements", - len - ))), + len => Err(Error::CustomError( + format_args!("Invalid Option: received array of {:?} elements", len) + .as_str() + .unwrap(), + )), } } } @@ -172,59 +180,64 @@ impl Deserialize for Option { /// /// There is no explicit `panic!` in this code, except a few `unreachable!`. /// -pub struct Deserializer { - data: Vec, +pub struct Deserializer<'a> { + data: &'a [u8], + pos: usize, } + +#[cfg(feature = "alloc")] impl From> for Deserializer { fn from(r: Vec) -> Self { - Deserializer { data: r } + Deserializer { data: r.as_slice() } } } -impl AsRef> for Deserializer { - fn as_ref(&self) -> &Vec { - &self.data +impl<'a> From<&'a [u8]> for Deserializer<'a> { + fn from(r: &'a [u8]) -> Self { + Deserializer { data: r, pos: 0 } } } -impl Display for Deserializer { +impl<'a> AsRef<[u8]> for Deserializer<'a> { + fn as_ref(&self) -> &[u8] { + self.data + } +} + +impl<'a> Display for Deserializer<'a> { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - f.write_str( - &self - .data - .iter() - .map(|b| format!("{:02x}", b)) - .collect::>() - .join(" "), - ) + self.data + .iter() + .map(|b| f.write_fmt(format_args!("{:02x}", b))) + .collect() } } -impl Deserializer { - pub fn inner(self) -> Vec { +impl<'a> Deserializer<'a> { + pub fn inner(self) -> &'a [u8] { self.data } #[inline] - fn get(&mut self, index: usize) -> Result { + fn get(&mut self, index: usize) -> Result<'a, &u8> { match self.data.get(index) { None => Err(Error::NotEnough(self.data.len(), index)), - Some(b) => Ok(*b), + Some(b) => Ok(b), } } #[inline] - fn u8(&mut self, index: usize) -> Result { + fn u8(&mut self, index: usize) -> Result<'a, u64> { let b = self.get(index)?; - Ok(b as u64) + Ok(*b as u64) } #[inline] - fn u16(&mut self, index: usize) -> Result { + fn u16(&mut self, index: usize) -> Result<'a, u64> { let b1 = self.u8(index)?; let b2 = self.u8(index + 1)?; Ok(b1 << 8 | b2) } #[inline] - fn u32(&mut self, index: usize) -> Result { + fn u32(&mut self, index: usize) -> Result<'a, u64> { let b1 = self.u8(index)?; let b2 = self.u8(index + 1)?; let b3 = self.u8(index + 2)?; @@ -232,7 +245,7 @@ impl Deserializer { Ok(b1 << 24 | b2 << 16 | b3 << 8 | b4) } #[inline] - fn u64(&mut self, index: usize) -> Result { + fn u64(&mut self, index: usize) -> Result<'a, u64> { let b1 = self.u8(index)?; let b2 = self.u8(index + 1)?; let b3 = self.u8(index + 2)?; @@ -260,11 +273,11 @@ impl Deserializer { /// assert!(cbor_type == Type::UnsignedInteger); /// ``` #[inline] - pub fn cbor_type(&mut self) -> Result { + pub fn cbor_type(&mut self) -> Result<'a, Type> { Ok(Type::from(self.get(0)?)) } #[inline] - fn cbor_expect_type(&mut self, t: Type) -> Result<()> { + fn cbor_expect_type(&mut self, t: Type) -> Result<'a, ()> { let t_ = self.cbor_type()?; if t_ != t { Err(Error::Expected(t, t_)) @@ -305,7 +318,7 @@ impl Deserializer { /// ``` /// #[inline] - pub fn cbor_len(&mut self) -> Result<(Len, usize)> { + pub fn cbor_len(&mut self) -> Result<'a, (Len, usize)> { let b: u8 = self.get(0)? & 0b0001_1111; match b { 0x00..=0x17 => Ok((Len::Len(b as u64), 0)), @@ -327,7 +340,7 @@ impl Deserializer { /// /// [`LenSz`]: ../enum.LenSz.html #[inline] - pub fn cbor_len_sz(&mut self) -> Result { + pub fn cbor_len_sz(&mut self) -> Result<'a, LenSz> { let b: u8 = self.get(0)? & 0b0001_1111; match b { 0x00..=0x17 => Ok(LenSz::Len(b as u64, Sz::Inline)), @@ -347,8 +360,8 @@ impl Deserializer { /// consume the given `len` from the underlying buffer. Skipped bytes are /// then lost, they cannot be retrieved for future references. #[inline] - pub fn advance(&mut self, len: usize) -> Result<()> { - self.data.drain(..len); + pub fn advance(&mut self, len: usize) -> Result<'a, ()> { + self.pos += len; Ok(()) } @@ -379,14 +392,14 @@ impl Deserializer { /// // the following line will panic: /// let integer = raw.unsigned_integer().unwrap(); /// ``` - pub fn unsigned_integer(&mut self) -> Result { + pub fn unsigned_integer(&mut self) -> Result<'a, u64> { Ok(self.unsigned_integer_sz()?.0) } /// Read an `UnsignedInteger` from the `Deserializer` with encoding information /// /// Same as `unsigned_integer` but returns the `Sz` (bytes used) in the encoding - pub fn unsigned_integer_sz(&mut self) -> Result<(u64, Sz)> { + pub fn unsigned_integer_sz(&mut self) -> Result<'a, (u64, Sz)> { self.cbor_expect_type(Type::UnsignedInteger)?; let len_sz = self.cbor_len_sz()?; match len_sz { @@ -414,7 +427,7 @@ impl Deserializer { /// /// assert_eq!(integer, -42); /// ``` - pub fn negative_integer(&mut self) -> Result { + pub fn negative_integer(&mut self) -> Result<'a, i64> { self.cbor_expect_type(Type::NegativeInteger)?; let (len, len_sz) = self.cbor_len()?; match len { @@ -431,7 +444,7 @@ impl Deserializer { /// Same as `negative_integer` but returns the `Sz` (bytes used) /// in the encoding as well as using a `i128` return type as `i64` /// does not cover the entire CBOR `nint` range. - pub fn negative_integer_sz(&mut self) -> Result<(i128, Sz)> { + pub fn negative_integer_sz(&mut self) -> Result<'a, (i128, Sz)> { self.cbor_expect_type(Type::NegativeInteger)?; let len_sz = self.cbor_len_sz()?; match len_sz { @@ -457,21 +470,21 @@ impl Deserializer { /// /// let bytes = raw.bytes().unwrap(); /// ``` - pub fn bytes(&mut self) -> Result> { + pub fn bytes(&mut self) -> Result<'a, &[u8]> { Ok(self.bytes_sz()?.0) } /// Read a Bytes from the Deserializer with encoding information /// /// Same as `bytes` but also returns `StringLenSz` for details about the encoding used. - pub fn bytes_sz(&mut self) -> Result<(Vec, StringLenSz)> { + pub fn bytes_sz(&mut self) -> Result<'a, (&[u8], StringLenSz)> { self.cbor_expect_type(Type::Bytes)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; match len_sz { LenSz::Indefinite => { - let mut bytes = vec![]; - let mut chunk_lens = Vec::new(); + let mut bytes: &[u8] = *[]; + let mut chunk_lens: [(u64, Sz)] = *[]; while self.cbor_type()? != Type::Special || !self.special_break()? { self.cbor_expect_type(Type::Bytes)?; let chunk_len_sz = self.cbor_len_sz()?; @@ -479,19 +492,19 @@ impl Deserializer { LenSz::Indefinite => return Err(Error::InvalidIndefiniteString), LenSz::Len(len, sz) => { self.advance(1 + sz.bytes_following())?; - bytes.extend_from_slice(&self.data[0..len as usize]); + bytes = + &[bytes, &self.data[self.pos..self.pos + len as usize]].concat(); self.advance(len as usize)?; - chunk_lens.push((len, sz)); + chunk_lens = [chunk_lens, *[(len, sz)]].concat(); } } } Ok((bytes, StringLenSz::Indefinite(chunk_lens))) } LenSz::Len(len, sz) => { - let bytes = &self.data[0..len as usize]; - let bytes_vec = Vec::from(bytes); + let bytes = &self.data[self.pos..self.pos + len as usize]; self.advance(len as usize)?; - Ok((bytes_vec, StringLenSz::Len(sz))) + Ok((bytes, StringLenSz::Len(sz))) } } } @@ -512,21 +525,21 @@ impl Deserializer { /// /// assert!(&*text == "text"); /// ``` - pub fn text(&mut self) -> Result { + pub fn text(&mut self) -> Result<'a, &str> { Ok(self.text_sz()?.0) } /// Read a Text from the Deserializer with encoding information /// /// Same as `text` but also returns `StringLenSz` for details about the encoding used. - pub fn text_sz(&mut self) -> Result<(String, StringLenSz)> { + pub fn text_sz(&mut self) -> Result<'a, (&str, StringLenSz)> { self.cbor_expect_type(Type::Text)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; match len_sz { LenSz::Indefinite => { - let mut text = String::new(); - let mut chunk_lens = Vec::new(); + let mut text: [&str] = *[]; + let mut chunk_lens: [(u64, Sz)] = *[]; while self.cbor_type()? != Type::Special || !self.special_break()? { self.cbor_expect_type(Type::Text)?; let chunk_len = self.cbor_len_sz()?; @@ -536,10 +549,10 @@ impl Deserializer { // rfc7049 forbids splitting UTF-8 characters across chunks so we must // read each chunk separately as a definite encoded UTF-8 string self.advance(1 + sz.bytes_following())?; - let bytes = &self.data[0..len as usize]; - let chunk_text = String::from_utf8_lossy(bytes).into_owned(); + let bytes = &self.data[self.pos..self.pos + len as usize]; + let chunk_text = core::str::from_utf8(bytes)?; self.advance(len as usize)?; - text.push_str(&chunk_text); + text.push_str(chunk_text); chunk_lens.push((len, sz)); } } @@ -547,8 +560,8 @@ impl Deserializer { Ok((text, StringLenSz::Indefinite(chunk_lens))) } LenSz::Len(len, sz) => { - let bytes = &self.data[0..len as usize]; - let text = String::from_utf8_lossy(bytes).into_owned(); + let bytes = &self.data[self.pos..self.pos + len as usize]; + let text = core::str::from_utf8(bytes)?; self.advance(len as usize)?; Ok((text, StringLenSz::Len(sz))) } @@ -558,9 +571,9 @@ impl Deserializer { // Internal helper to decode a series of `len` items using a function. If // `len` is indefinite, decode until a `Special::Break`. If `len` is // definite, decode that many items. - fn internal_items_with(&mut self, len: Len, mut f: F) -> Result<()> + fn internal_items_with(&mut self, len: Len, mut f: F) -> Result<'a, ()> where - F: FnMut(&mut Self) -> Result<()>, + F: FnMut(&mut Self) -> Result<'a, ()>, { match len { Len::Indefinite => { @@ -594,7 +607,7 @@ impl Deserializer { /// assert_eq!(len, Len::Len(6)); /// ``` /// - pub fn array(&mut self) -> Result { + pub fn array(&mut self) -> Result<'a, Len> { self.cbor_expect_type(Type::Array)?; let (len, sz) = self.cbor_len()?; self.advance(1 + sz)?; @@ -605,7 +618,7 @@ impl Deserializer { /// /// Same as `array` but returns the `LenSz` instead which contains /// additional information about the encoding used for the length - pub fn array_sz(&mut self) -> Result { + pub fn array_sz(&mut self) -> Result<'a, LenSz> { self.cbor_expect_type(Type::Array)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; @@ -617,16 +630,16 @@ impl Deserializer { /// This works with either definite or indefinite arrays. Each call to the /// function should decode one item. If the function returns an error, /// decoding stops and returns that error. - pub fn array_with(&mut self, f: F) -> Result<()> + pub fn array_with(&mut self, f: F) -> Result<'a, ()> where - F: FnMut(&mut Self) -> Result<()>, + F: FnMut(&mut Self) -> Result<'a, ()>, { let len = self.array()?; self.internal_items_with(len, f) } /// Expect an array of a specified length. Must be a definite-length array. - pub fn tuple(&mut self, expected_len: u64, error_location: &'static str) -> Result<()> { + pub fn tuple(&mut self, expected_len: u64, error_location: &'static str) -> Result<'a, ()> { let actual_len = self.array()?; match actual_len { Len::Len(len) if expected_len == len => Ok(()), @@ -651,7 +664,7 @@ impl Deserializer { /// assert_eq!(len, Len::Len(2)); /// ``` /// - pub fn map(&mut self) -> Result { + pub fn map(&mut self) -> Result<'a, Len> { self.cbor_expect_type(Type::Map)?; let (len, sz) = self.cbor_len()?; self.advance(1 + sz)?; @@ -662,7 +675,7 @@ impl Deserializer { /// /// Same as `map` but returns the `LenSz` instead which contains /// additional information about the encoding used for the length - pub fn map_sz(&mut self) -> Result { + pub fn map_sz(&mut self) -> Result<'a, LenSz> { self.cbor_expect_type(Type::Map)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; @@ -674,9 +687,9 @@ impl Deserializer { /// This works with either definite or indefinite maps. Each call to the /// function should decode one key followed by one value. If the function /// returns an error, decoding stops and returns that error. - pub fn map_with(&mut self, f: F) -> Result<()> + pub fn map_with(&mut self, f: F) -> Result<'a, ()> where - F: FnMut(&mut Self) -> Result<()>, + F: FnMut(&mut Self) -> Result<'a, ()>, { let len = self.map()?; self.internal_items_with(len, f) @@ -700,14 +713,14 @@ impl Deserializer { /// assert_eq!("text", &*raw.text().unwrap()); /// ``` /// - pub fn tag(&mut self) -> Result { + pub fn tag(&mut self) -> Result<'a, u64> { Ok(self.tag_sz()?.0) } /// CBOR Tag with encoding information /// /// Same as `tag` but returns the `Sz` (bytes used) in the encoding - pub fn tag_sz(&mut self) -> Result<(u64, Sz)> { + pub fn tag_sz(&mut self) -> Result<'a, (u64, Sz)> { self.cbor_expect_type(Type::Tag)?; match self.cbor_len_sz()? { LenSz::Indefinite => Err(Error::IndefiniteLenNotSupported(Type::Tag)), @@ -718,7 +731,7 @@ impl Deserializer { } } - pub fn set_tag(&mut self) -> Result<()> { + pub fn set_tag(&mut self) -> Result<'a, ()> { let tag = self.tag()?; if tag != 258 { return Err(Error::ExpectedSetTag); @@ -731,7 +744,7 @@ impl Deserializer { /// /// Useful when decoding a variable-length array or map where the items may themselves use /// `Special`, such as bool values. - pub fn special_break(&mut self) -> Result { + pub fn special_break(&mut self) -> Result<'a, bool> { self.cbor_expect_type(Type::Special)?; let b = self.get(0)? & 0b0001_1111; if b == 0x1f { @@ -742,7 +755,7 @@ impl Deserializer { } } - pub fn special(&mut self) -> Result { + pub fn special(&mut self) -> Result<'a, Special> { self.cbor_expect_type(Type::Special)?; let b = self.get(0)? & 0b0001_1111; match b { @@ -798,26 +811,26 @@ impl Deserializer { } } - pub fn bool(&mut self) -> Result { + pub fn bool(&mut self) -> Result<'a, &bool> { self.special()?.unwrap_bool() } - pub fn float(&mut self) -> Result { + pub fn float(&mut self) -> Result<'a, &f64> { self.special()?.unwrap_float() } - pub fn deserialize(&mut self) -> Result + pub fn deserialize(&mut self) -> Result<'a, T> where - T: Deserialize, + T: Deserialize<'a>, { Deserialize::deserialize(self) } /// Deserialize a value of type `T` and check that there is no /// trailing data. - pub fn deserialize_complete(&mut self) -> Result + pub fn deserialize_complete(&mut self) -> Result<'a, T> where - T: Deserialize, + T: Deserialize<'a>, { let v = self.deserialize()?; if !self.data.is_empty() { @@ -833,8 +846,8 @@ impl Deserializer { macro_rules! deserialize_array { ( $( $x:expr ),* ) => { $( - impl Deserialize for [u8; $x] { - fn deserialize(raw: &mut Deserializer) -> Result { + impl<'a> Deserialize<'a> for [u8; $x] { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { let mut bytes = [0u8; $x]; let len = raw.array()?; @@ -869,6 +882,9 @@ deserialize_array!( #[allow(clippy::bool_assert_comparison)] mod test { use super::*; + use alloc::collections::BTreeMap; + use alloc::vec; + use alloc::vec::Vec; #[test] fn negative_integer() { @@ -1225,7 +1241,7 @@ mod test { ); assert_eq!( raw.bytes_sz().unwrap(), - (indef_bytes, StringLenSz::Indefinite(indef_lens)) + (indef_bytes, StringLenSz::Indefinite(*indef_lens)) ); } @@ -1281,7 +1297,7 @@ mod test { raw.text_sz().unwrap(), ( "HelloWorld日本語9ABC".into(), - StringLenSz::Indefinite(indef_lens) + StringLenSz::Indefinite(*indef_lens) ) ); } diff --git a/src/error.rs b/src/error.rs index 1f0313b..6bcbffc 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,13 +1,12 @@ -use alloc::string::{FromUtf8Error, String}; -use alloc::vec::Vec; use core::fmt; +use core::str::Utf8Error; use len; use types::Type; /// all expected error for cbor parsing and serialising #[derive(Debug)] -pub enum Error { +pub enum Error<'a> { ExpectedU8, ExpectedU16, ExpectedU32, @@ -27,22 +26,22 @@ pub enum Error { UnknownLenType(u8), IndefiniteLenNotSupported(Type), WrongLen(u64, len::Len, &'static str), - InvalidTextError(FromUtf8Error), - CannotParse(Type, Vec), + InvalidTextError(Utf8Error), + CannotParse(Type, &'a [u8]), TrailingData, InvalidIndefiniteString, InvalidLenPassed(len::Sz), InvalidNint(i128), - CustomError(String), + CustomError(&'a str), } -impl From for Error { - fn from(e: FromUtf8Error) -> Self { +impl From for Error<'_> { + fn from(e: Utf8Error) -> Self { Error::InvalidTextError(e) } } -impl fmt::Display for Error { +impl fmt::Display for Error<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use Error::*; match self { diff --git a/src/len.rs b/src/len.rs index 7d44323..2637338 100644 --- a/src/len.rs +++ b/src/len.rs @@ -1,5 +1,3 @@ -use alloc::vec::Vec; - /// CBOR len: either a fixed size or an indefinite length. #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum Len { @@ -91,8 +89,8 @@ impl LenSz { /// Definite encoding strings can vary by how many bytes are used to encode /// the length e.g. 4 can be represented inline in the type, or in 1/2/4/8 /// additional bytes -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Eq)] pub enum StringLenSz { - Indefinite(Vec<(u64, Sz)>), + Indefinite([(u64, Sz)]), Len(Sz), } diff --git a/src/lib.rs b/src/lib.rs index 641b2bd..f18ae8f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -92,12 +92,14 @@ const CBOR_PAYLOAD_LENGTH_U64: u8 = 27; /// [`Serialize`](./se/trait.Serialize.html) and /// [`Deserialize`](./de/trait.Deserialize.html). /// -pub fn test_encode_decode(v: &V) -> Result { +pub fn test_encode_decode<'a, V: Sized + PartialEq + Serialize + Deserialize<'a>>( + v: &'a V, +) -> Result { let mut se = se::Serializer::new_vec(); v.serialize(&mut se)?; let bytes = se.finalize(); - let mut raw = de::Deserializer::from(bytes); + let mut raw = de::Deserializer::from(bytes.as_slice()); let v_ = Deserialize::deserialize(&mut raw)?; Ok(v == &v_) diff --git a/src/result.rs b/src/result.rs index 43ed212..58b04e4 100644 --- a/src/result.rs +++ b/src/result.rs @@ -1,4 +1,4 @@ use Error; /// `Result` type for CBOR serialisation and deserialisation. -pub type Result = core::result::Result; +pub type Result<'a, T> = core::result::Result>; diff --git a/src/se.rs b/src/se.rs index 166b2a5..5f0854d 100644 --- a/src/se.rs +++ b/src/se.rs @@ -1005,7 +1005,7 @@ mod test { 0xBA, 0xAD, 0xF0, 0x0D, 0xCA, 0xFE, 0xD0, 0x0D, 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBE, 0xEF, ]; - let indef_lens = vec![ + let indef_lens = [ (4, Sz::Inline), (4, Sz::One), (4, Sz::Two), @@ -1024,7 +1024,7 @@ mod test { .unwrap() .write_bytes_sz(vec![0xBE, 0xEF], StringLenSz::Len(Sz::Eight)) .unwrap() - .write_bytes_sz(indef_bytes, StringLenSz::Indefinite(indef_lens)) + .write_bytes_sz(indef_bytes, StringLenSz::Indefinite(*indef_lens)) .unwrap(); let bytes = serializer.finalize(); assert_eq!(bytes, expected_bytes); @@ -1050,7 +1050,7 @@ mod test { expected_bytes.extend_from_slice(&slice[..]); } expected_bytes.push(0xFF); - let indef_lens = vec![ + let indef_lens = [ (5, Sz::Inline), (5, Sz::One), (9, Sz::Two), @@ -1069,7 +1069,7 @@ mod test { .unwrap() .write_text_sz("ABC", StringLenSz::Len(Sz::Eight)) .unwrap() - .write_text_sz("HelloWorld日本語9ABC", StringLenSz::Indefinite(indef_lens)) + .write_text_sz("HelloWorld日本語9ABC", StringLenSz::Indefinite(*indef_lens)) .unwrap(); let bytes = serializer.finalize(); assert_eq!(bytes, expected_bytes); diff --git a/src/types.rs b/src/types.rs index 2f635d0..ef9b586 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,4 +1,3 @@ -use alloc::format; use error::Error; #[cfg(test)] use quickcheck::{Arbitrary, Gen}; @@ -69,13 +68,14 @@ pub enum Special { } impl Special { #[inline] - pub fn unwrap_bool(&self) -> Result { + pub fn unwrap_bool(&self) -> Result<&bool> { match self { - Special::Bool(b) => Ok(*b), - _ => Err(Error::CustomError(format!( - "Expected Special::Bool, received {:?}", - self - ))), + Special::Bool(b) => Ok(b), + _ => Err(Error::CustomError( + format_args!("Expected Special::Bool, received {:?}", self) + .as_str() + .unwrap(), + )), } } @@ -83,10 +83,11 @@ impl Special { pub fn unwrap_null(&self) -> Result<()> { match self { Special::Null => Ok(()), - _ => Err(Error::CustomError(format!( - "Expected Special::Null, received {:?}", - self - ))), + _ => Err(Error::CustomError( + format_args!("Expected Special::Null, received {:?}", self) + .as_str() + .unwrap(), + )), } } @@ -94,32 +95,35 @@ impl Special { pub fn unwrap_undefined(&self) -> Result<()> { match self { Special::Undefined => Ok(()), - _ => Err(Error::CustomError(format!( - "Expected Special::Undefined, received {:?}", - self - ))), + _ => Err(Error::CustomError( + format_args!("Expected Special::Undefined, received {:?}", self) + .as_str() + .unwrap(), + )), } } #[inline] - pub fn unwrap_unassigned(&self) -> Result { + pub fn unwrap_unassigned(&self) -> Result<&u8> { match self { - Special::Unassigned(v) => Ok(*v), - _ => Err(Error::CustomError(format!( - "Expected Special::Unassigned, received {:?}", - self - ))), + Special::Unassigned(v) => Ok(v), + _ => Err(Error::CustomError( + format_args!("Expected Special::Unassigned, received {:?}", self) + .as_str() + .unwrap(), + )), } } #[inline] - pub fn unwrap_float(&self) -> Result { + pub fn unwrap_float(&self) -> Result<&f64> { match self { - Special::Float(f) => Ok(*f), - _ => Err(Error::CustomError(format!( - "Expected Special::Float, received {:?}", - self - ))), + Special::Float(f) => Ok(f), + _ => Err(Error::CustomError( + format_args!("Expected Special::Float, received {:?}", self) + .as_str() + .unwrap(), + )), } } @@ -127,10 +131,11 @@ impl Special { pub fn unwrap_break(&self) -> Result<()> { match self { Special::Break => Ok(()), - _ => Err(Error::CustomError(format!( - "Expected Special::Break, received {:?}", - self - ))), + _ => Err(Error::CustomError( + format_args!("Expected Special::Break, received {:?}", self) + .as_str() + .unwrap(), + )), } } } diff --git a/src/value.rs b/src/value.rs index 954b972..ff3af94 100644 --- a/src/value.rs +++ b/src/value.rs @@ -9,11 +9,6 @@ //! //! This is why all the objects here are marked as deprecated -use alloc::boxed::Box; -use alloc::collections::BTreeMap; -use alloc::format; -use alloc::string::String; -use alloc::vec::Vec; #[cfg(test)] use core::iter::repeat_with; @@ -30,14 +25,14 @@ use types::{Special, Type}; /// CBOR Object key, represents the possible supported values for /// a CBOR key in a CBOR Map. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub enum ObjectKey { +pub enum ObjectKey<'a> { Integer(u64), - Bytes(Vec), - Text(String), + Bytes(&'a [u8]), + Text(&'a str), } -impl ObjectKey { +impl<'a> ObjectKey<'a> { /// convert the given `ObjectKey` into a CBOR [`Value`](./struct.Value.html) - pub fn value(self) -> Value { + pub fn value(self) -> Value<'a> { match self { ObjectKey::Integer(v) => Value::U64(v), ObjectKey::Bytes(v) => Value::Bytes(v), @@ -45,7 +40,7 @@ impl ObjectKey { } } } -impl Serialize for ObjectKey { +impl<'a> Serialize for ObjectKey<'a> { fn serialize<'se>(&self, serializer: &'se mut Serializer) -> Result<&'se mut Serializer> { match self { ObjectKey::Integer(ref v) => serializer.write_unsigned_integer(*v), @@ -54,16 +49,17 @@ impl Serialize for ObjectKey { } } } -impl Deserialize for ObjectKey { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a> Deserialize<'a> for ObjectKey<'_> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { match raw.cbor_type()? { Type::UnsignedInteger => Ok(ObjectKey::Integer(raw.unsigned_integer()?)), Type::Bytes => Ok(ObjectKey::Bytes(raw.bytes()?)), Type::Text => Ok(ObjectKey::Text(raw.text()?)), - t => Err(Error::CustomError(format!( - "Type `{:?}' is not a support type for CBOR Map's key", - t - ))), + t => Err(Error::CustomError( + format_args!("Type `{:?}' is not a support type for CBOR Map's key", t) + .as_str() + .unwrap(), + )), } } } @@ -75,20 +71,23 @@ impl Deserialize for ObjectKey { /// so. However it is handy for debugging or reverse a given protocol. /// #[derive(Debug, Clone, PartialEq, PartialOrd)] -pub enum Value { +pub enum Value<'a> { U64(u64), I64(i64), - Bytes(Vec), - Text(String), - Array(Vec), - IArray(Vec), - Object(BTreeMap), - IObject(BTreeMap), - Tag(u64, Box), + Bytes(&'a [u8]), + Text(&'a str), + Array(&'a [Value<'a>]), + IArray(&'a [Value<'a>]), + #[cfg(feature = "alloc")] + Object(BTreeMap, Value<'a>>), + #[cfg(feature = "alloc")] + IObject(BTreeMap, Value<'a>>), + #[cfg(feature = "alloc")] + Tag(u64, Box>), Special(Special), } -impl Serialize for Value { +impl Serialize for Value<'_> { fn serialize<'se>(&self, serializer: &'se mut Serializer) -> Result<&'se mut Serializer> { match self { Value::U64(ref v) => serializer.write_unsigned_integer(*v), @@ -97,14 +96,14 @@ impl Serialize for Value { Value::Text(ref v) => serializer.write_text(v), Value::Array(ref v) => { serializer.write_array(Len::Len(v.len() as u64))?; - for element in v { + for element in v.iter() { serializer.serialize(element)?; } Ok(serializer) } Value::IArray(ref v) => { serializer.write_array(Len::Indefinite)?; - for element in v { + for element in v.iter() { serializer.serialize(element)?; } serializer.write_special(Special::Break) @@ -128,8 +127,8 @@ impl Serialize for Value { } } } -impl Deserialize for Value { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a> Deserialize<'a> for Value<'_> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { match raw.cbor_type()? { Type::UnsignedInteger => Ok(Value::U64(raw.unsigned_integer()?)), Type::NegativeInteger => Ok(Value::I64(raw.negative_integer()?)), @@ -295,9 +294,6 @@ impl Arbitrary for Value { #[cfg(test)] mod test { - use alloc::borrow::ToOwned; - use alloc::vec; - use super::super::test_encode_decode; use super::*; @@ -327,48 +323,43 @@ mod test { #[test] fn bytes() { - assert!(test_encode_decode(&Value::Bytes(vec![])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(vec![0; 23])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(vec![0; 24])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(vec![0; 256])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(vec![0; 10293])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(vec![0; 99999000])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(&[])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(&[0; 23])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(&[0; 24])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(&[0; 256])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(&[0; 10293])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(&[0; 99999000])).unwrap()); } #[test] fn text() { - assert!(test_encode_decode(&Value::Text("".to_owned())).unwrap()); - assert!(test_encode_decode(&Value::Text("hellow world".to_owned())).unwrap()); - assert!(test_encode_decode(&Value::Text("some sentence, some sentence... some sentence...some sentence, some sentence... some sentence...".to_owned())).unwrap()); + assert!(test_encode_decode(&Value::Text("")).unwrap()); + assert!(test_encode_decode(&Value::Text("hellow world")).unwrap()); + assert!(test_encode_decode(&Value::Text("some sentence, some sentence... some sentence...some sentence, some sentence... some sentence...")).unwrap()); } #[test] fn array() { - assert!(test_encode_decode(&Value::Array(vec![])).unwrap()); - assert!(test_encode_decode(&Value::Array(vec![ - Value::U64(0), - Value::Text("some text".to_owned()) - ])) - .unwrap()); + assert!(test_encode_decode(&Value::Array(&[])).unwrap()); + assert!( + test_encode_decode(&Value::Array(&[Value::U64(0), Value::Text("some text")])).unwrap() + ); } #[test] fn iarray() { - assert!(test_encode_decode(&Value::IArray(vec![])).unwrap()); - assert!(test_encode_decode(&Value::IArray(vec![ - Value::U64(0), - Value::Text("some text".to_owned()) - ])) - .unwrap()); + assert!(test_encode_decode(&Value::IArray(&[])).unwrap()); + assert!( + test_encode_decode(&Value::IArray(&[Value::U64(0), Value::Text("some text")])).unwrap() + ); } + #[cfg(feature = "alloc")] #[test] fn tag() { assert!(test_encode_decode(&Value::Tag(23, Box::new(Value::U64(0)))).unwrap()); - assert!(test_encode_decode(&Value::Tag(24, Box::new(Value::Bytes(vec![0; 32])))).unwrap()); - assert!( - test_encode_decode(&Value::Tag(0x1ff, Box::new(Value::Bytes(vec![0; 624])))).unwrap() - ); + assert!(test_encode_decode(&Value::Tag(24, Box::new(Value::Bytes(&[0; 32])))).unwrap()); + assert!(test_encode_decode(&Value::Tag(0x1ff, Box::new(Value::Bytes(&[0; 624])))).unwrap()); } quickcheck! { From 3886cbbb2a42b49964e3012515a1dd31ef78b6a1 Mon Sep 17 00:00:00 2001 From: SimonIT Date: Thu, 14 Mar 2024 18:24:52 +0100 Subject: [PATCH 02/11] Fix some lifetimes, use slice in serializer --- src/de.rs | 43 +++++++------ src/lib.rs | 23 ++++--- src/se.rs | 166 ++++++++++++++++++++++++++++++++------------------- src/types.rs | 12 ++-- src/value.rs | 34 +++++++---- 5 files changed, 175 insertions(+), 103 deletions(-) diff --git a/src/de.rs b/src/de.rs index fd7293c..5baeca9 100644 --- a/src/de.rs +++ b/src/de.rs @@ -8,7 +8,7 @@ use alloc::string::String; use alloc::string::ToString; #[cfg(feature = "alloc")] use alloc::vec::Vec; -use core::fmt::{Display, Formatter, Write}; +use core::fmt::{Display, Formatter}; use error::Error; use len::{Len, LenSz, StringLenSz, Sz}; use result::Result; @@ -61,7 +61,7 @@ impl<'a> Deserialize<'a> for u64 { impl<'a> Deserialize<'a> for bool { fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { - raw.bool().cloned() + raw.bool() } } @@ -73,7 +73,13 @@ impl<'a> Deserialize<'a> for f32 { impl<'a> Deserialize<'a> for f64 { fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { - raw.float().cloned() + raw.float() + } +} + +impl<'a> Deserialize<'a> for &'a str { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + raw.text() } } @@ -85,7 +91,7 @@ impl<'a> Deserialize<'a> for String { } #[cfg(feature = "alloc")] -impl Deserialize for Vec { +impl<'a, T: Deserialize<'a>> Deserialize<'a> for Vec { fn deserialize(raw: &mut Deserializer) -> Result<'a, Self> { let mut vec = Vec::new(); raw.array_with(|raw| { @@ -96,8 +102,8 @@ impl Deserialize for Vec { } } #[cfg(feature = "alloc")] -impl Deserialize for BTreeMap { - fn deserialize(raw: &mut Deserializer) -> Result<'a, Self> { +impl<'a, K: Deserialize + Ord, V: Deserialize<'a>> Deserialize<'a> for BTreeMap { + fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { let mut vec = BTreeMap::new(); raw.map_with(|raw| { let k = Deserialize::deserialize(raw)?; @@ -188,7 +194,10 @@ pub struct Deserializer<'a> { #[cfg(feature = "alloc")] impl From> for Deserializer { fn from(r: Vec) -> Self { - Deserializer { data: r.as_slice() } + Deserializer { + data: r.as_slice(), + pos: 0, + } } } @@ -220,7 +229,7 @@ impl<'a> Deserializer<'a> { #[inline] fn get(&mut self, index: usize) -> Result<'a, &u8> { - match self.data.get(index) { + match self.data.get(self.pos + index) { None => Err(Error::NotEnough(self.data.len(), index)), Some(b) => Ok(b), } @@ -470,14 +479,14 @@ impl<'a> Deserializer<'a> { /// /// let bytes = raw.bytes().unwrap(); /// ``` - pub fn bytes(&mut self) -> Result<'a, &[u8]> { + pub fn bytes(&mut self) -> Result<'a, &'a [u8]> { Ok(self.bytes_sz()?.0) } /// Read a Bytes from the Deserializer with encoding information /// /// Same as `bytes` but also returns `StringLenSz` for details about the encoding used. - pub fn bytes_sz(&mut self) -> Result<'a, (&[u8], StringLenSz)> { + pub fn bytes_sz(&mut self) -> Result<'a, (&'a [u8], StringLenSz)> { self.cbor_expect_type(Type::Bytes)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; @@ -525,14 +534,14 @@ impl<'a> Deserializer<'a> { /// /// assert!(&*text == "text"); /// ``` - pub fn text(&mut self) -> Result<'a, &str> { + pub fn text(&mut self) -> Result<'a, &'a str> { Ok(self.text_sz()?.0) } /// Read a Text from the Deserializer with encoding information /// /// Same as `text` but also returns `StringLenSz` for details about the encoding used. - pub fn text_sz(&mut self) -> Result<'a, (&str, StringLenSz)> { + pub fn text_sz(&mut self) -> Result<'a, (&'a str, StringLenSz)> { self.cbor_expect_type(Type::Text)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; @@ -811,11 +820,11 @@ impl<'a> Deserializer<'a> { } } - pub fn bool(&mut self) -> Result<'a, &bool> { + pub fn bool(&mut self) -> Result<'a, bool> { self.special()?.unwrap_bool() } - pub fn float(&mut self) -> Result<'a, &f64> { + pub fn float(&mut self) -> Result<'a, f64> { self.special()?.unwrap_float() } @@ -833,10 +842,10 @@ impl<'a> Deserializer<'a> { T: Deserialize<'a>, { let v = self.deserialize()?; - if !self.data.is_empty() { - Err(Error::TrailingData) - } else { + if self.pos < self.data.len() { Ok(v) + } else { + Err(Error::TrailingData) } } } diff --git a/src/lib.rs b/src/lib.rs index f18ae8f..5b1fc3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -92,15 +92,24 @@ const CBOR_PAYLOAD_LENGTH_U64: u8 = 27; /// [`Serialize`](./se/trait.Serialize.html) and /// [`Deserialize`](./de/trait.Deserialize.html). /// -pub fn test_encode_decode<'a, V: Sized + PartialEq + Serialize + Deserialize<'a>>( - v: &'a V, -) -> Result { - let mut se = se::Serializer::new_vec(); - v.serialize(&mut se)?; +#[cfg(test)] +pub fn test_encode_decode< + 'a, + 'b, + 'c, + B: Deserialize<'c>, + V: Sized + PartialEq + Serialize + Deserialize<'a>, +>( + data: &'c mut [u8], + v: &'c V, +) -> Result<'b, bool> { + let mut se = se::Serializer::new(data); + v.serialize(&mut se) + .map_err(|e| Error::CustomError("FAIL!"))?; let bytes = se.finalize(); - let mut raw = de::Deserializer::from(bytes.as_slice()); - let v_ = Deserialize::deserialize(&mut raw)?; + let mut raw = de::Deserializer::from(bytes); + let v_ = Deserialize::deserialize(&mut raw).map_err(|e| Error::CustomError("FAIL!"))?; Ok(v == &v_) } diff --git a/src/se.rs b/src/se.rs index 5f0854d..b2abd31 100644 --- a/src/se.rs +++ b/src/se.rs @@ -9,55 +9,88 @@ use result::Result; use types::{Special, Type}; pub trait Serialize { - fn serialize<'a>(&self, serializer: &'a mut Serializer) -> Result<&'a mut Serializer>; + fn serialize<'a>( + &'a self, + serializer: &'a mut Serializer<'a>, + ) -> Result<'a, &'a mut Serializer<'a>>; } impl<'a, T: Serialize> Serialize for &'a T { - fn serialize<'se>(&self, serializer: &'se mut Serializer) -> Result<&'se mut Serializer> { + fn serialize<'se>( + &'se self, + serializer: &'se mut Serializer<'se>, + ) -> Result<'se, &'se mut Serializer<'se>> { serializer.serialize(*self) } } impl Serialize for u64 { - fn serialize<'a>(&self, serializer: &'a mut Serializer) -> Result<&'a mut Serializer> { + fn serialize<'a>( + &self, + serializer: &'a mut Serializer<'a>, + ) -> Result<'a, &'a mut Serializer<'a>> { serializer.write_unsigned_integer(*self) } } impl Serialize for u32 { - fn serialize<'a>(&self, serializer: &'a mut Serializer) -> Result<&'a mut Serializer> { + fn serialize<'a>( + &self, + serializer: &'a mut Serializer<'a>, + ) -> Result<'a, &'a mut Serializer<'a>> { serializer.write_unsigned_integer((*self) as u64) } } impl Serialize for u16 { - fn serialize<'a>(&self, serializer: &'a mut Serializer) -> Result<&'a mut Serializer> { + fn serialize<'a>( + &self, + serializer: &'a mut Serializer<'a>, + ) -> Result<'a, &'a mut Serializer<'a>> { serializer.write_unsigned_integer((*self) as u64) } } impl Serialize for u8 { - fn serialize<'a>(&self, serializer: &'a mut Serializer) -> Result<&'a mut Serializer> { + fn serialize<'a>( + &self, + serializer: &'a mut Serializer<'a>, + ) -> Result<'a, &'a mut Serializer<'a>> { serializer.write_unsigned_integer((*self) as u64) } } impl Serialize for bool { - fn serialize<'a>(&self, serializer: &'a mut Serializer) -> Result<&'a mut Serializer> { + fn serialize<'a>( + &self, + serializer: &'a mut Serializer<'a>, + ) -> Result<'a, &'a mut Serializer<'a>> { serializer.write_special(Special::Bool(*self)) } } impl Serialize for f32 { - fn serialize<'a>(&self, serializer: &'a mut Serializer) -> Result<&'a mut Serializer> { + fn serialize<'a>( + &self, + serializer: &'a mut Serializer<'a>, + ) -> Result<'a, &'a mut Serializer<'a>> { serializer.write_special(Special::Float((*self) as f64)) } } impl Serialize for f64 { - fn serialize<'a>(&self, serializer: &'a mut Serializer) -> Result<&'a mut Serializer> { + fn serialize<'a>( + &self, + serializer: &'a mut Serializer<'a>, + ) -> Result<'a, &'a mut Serializer<'a>> { serializer.write_special(Special::Float(*self)) } } impl Serialize for String { - fn serialize<'a>(&self, serializer: &'a mut Serializer) -> Result<&'a mut Serializer> { + fn serialize<'a>( + &self, + serializer: &'a mut Serializer<'a>, + ) -> Result<'a, &'a mut Serializer<'a>> { serializer.write_text(self) } } -impl<'a> Serialize for &'a [u8] { - fn serialize<'b>(&self, serializer: &'b mut Serializer) -> Result<&'b mut Serializer> { +impl<'b> Serialize for &'b [u8] { + fn serialize<'a>( + &self, + serializer: &'a mut Serializer<'a>, + ) -> Result<'a, &'a mut Serializer<'a>> { serializer.write_bytes(self) } } @@ -66,7 +99,10 @@ where A: Serialize, B: Serialize, { - fn serialize<'b>(&self, serializer: &'b mut Serializer) -> Result<&'b mut Serializer> { + fn serialize<'b>( + &'b self, + serializer: &'b mut Serializer<'b>, + ) -> Result<'b, &'b mut Serializer<'b>> { serializer .write_array(Len::Len(2))? .serialize(self.0)? @@ -79,7 +115,10 @@ where B: Serialize, C: Serialize, { - fn serialize<'b>(&self, serializer: &'b mut Serializer) -> Result<&'b mut Serializer> { + fn serialize<'b>( + &'b self, + serializer: &'b mut Serializer<'b>, + ) -> Result<'b, &'b mut Serializer<'b>> { serializer .write_array(Len::Len(3))? .serialize(self.0)? @@ -92,7 +131,10 @@ impl Serialize for Option where T: Serialize, { - fn serialize<'a>(&self, serializer: &'a mut Serializer) -> Result<&'a mut Serializer> { + fn serialize<'a>( + &'a self, + serializer: &'a mut Serializer<'a>, + ) -> Result<'a, &'a mut Serializer<'a>> { match self { None => serializer.write_array(Len::Len(0)), Some(x) => serializer.write_array(Len::Len(1))?.serialize(x), @@ -106,19 +148,19 @@ where /// pub fn serialize_fixed_map<'a, C, K, V, W>( data: C, - serializer: &mut Serializer, -) -> Result<&mut Serializer> + serializer: &'a mut Serializer<'a>, +) -> Result<'a, &'a mut Serializer<'a>> where K: 'a + Serialize, V: 'a + Serialize, C: Iterator + ExactSizeIterator, { - serializer.write_map(Len::Len(data.len() as u64))?; + let mut s = serializer.write_map(Len::Len(data.len() as u64))?; for element in data { - Serialize::serialize(element.0, serializer)?; - Serialize::serialize(element.1, serializer)?; + s = Serialize::serialize(element.0, s)?; + s = Serialize::serialize(element.1, s)?; } - Ok(serializer) + Ok(s) } /// helper function to serialise a collection of T as a fixed number of element @@ -127,53 +169,53 @@ where /// pub fn serialize_fixed_array<'a, C, T>( data: C, - serializer: &mut Serializer, -) -> Result<&mut Serializer> + serializer: &'a mut Serializer<'a>, +) -> Result<'a, &'a mut Serializer<'a>> where T: 'a + Serialize, C: Iterator + ExactSizeIterator, { - serializer.write_array(Len::Len(data.len() as u64))?; + let mut s = serializer.write_array(Len::Len(data.len() as u64))?; for element in data { - Serialize::serialize(element, serializer)?; + s = Serialize::serialize(element, s)?; } - Ok(serializer) + Ok(s) } /// helper function to serialise a map of indefinite number of elements. /// pub fn serialize_indefinite_map<'a, C, K, V, W>( data: C, - serializer: &mut Serializer, -) -> Result<&mut Serializer> + serializer: &'a mut Serializer<'a>, +) -> Result<'a, &'a mut Serializer<'a>> where K: 'a + Serialize, V: 'a + Serialize, C: Iterator, { - serializer.write_map(Len::Indefinite)?; + let mut s = serializer.write_map(Len::Indefinite)?; for element in data { - Serialize::serialize(element.0, serializer)?; - Serialize::serialize(element.1, serializer)?; + s = Serialize::serialize(element.0, s)?; + s = Serialize::serialize(element.1, s)?; } - serializer.write_special(Special::Break) + s.write_special(Special::Break) } /// helper function to serialise a collection of T as a indefinite number of element /// pub fn serialize_indefinite_array<'a, C, T, W>( data: C, - serializer: &mut Serializer, -) -> Result<&mut Serializer> + serializer: &'a mut Serializer<'a>, +) -> Result<'a, &'a mut Serializer<'a>> where T: 'a + Serialize, C: Iterator, { - serializer.write_array(Len::Indefinite)?; + let mut s = serializer.write_array(Len::Indefinite)?; for element in data { - Serialize::serialize(element, serializer)?; + s = Serialize::serialize(element, s)?; } - serializer.write_special(Special::Break) + s.write_special(Special::Break) } /// helper function to serialise cbor in cbor @@ -192,7 +234,10 @@ where /// serializer.write_bytes(&se.finalize()).unwrap(); /// ``` /// -pub fn serialize_cbor_in_cbor(data: T, serializer: &mut Serializer) -> Result<&mut Serializer> +pub fn serialize_cbor_in_cbor<'a, T>( + data: T, + serializer: &'a mut Serializer<'a>, +) -> Result<'a, &'a mut Serializer<'a>> where T: Serialize, { @@ -211,18 +256,18 @@ const DEFAULT_CAPACITY: usize = 512; /// [`std::io::Write`](https://doc.rust-lang.org/std/io/trait.Write.html). /// #[derive(Debug)] -pub struct Serializer { - data: Vec, +pub struct Serializer<'a> { + data: &'a mut [u8], } -impl Serializer { +impl<'a> Serializer<'a> { /// extend the serializer with the given bytes /// /// This is not encoding the given bytes in the CBOR format. More a way /// to add already CBOR encoded data or to add any bytes that may suite /// your protocol. pub fn write_raw_bytes(&mut self, bytes: &[u8]) -> Result<&mut Self> { - self.data.extend_from_slice(bytes); + self.data.copy_from_slice(bytes); Ok(self) } @@ -233,13 +278,14 @@ impl Serializer { /// /// let serializer = Serializer::new_vec(); /// ``` + #[cfg(feature = "alloc")] #[inline] pub fn new_vec() -> Self { - Serializer::new(Vec::with_capacity(DEFAULT_CAPACITY)) + Serializer::new(Vec::with_capacity(DEFAULT_CAPACITY).as_mut_slice()) } #[inline] - pub fn new(w: Vec) -> Self { + pub fn new(w: &'a mut [u8]) -> Self { Serializer { data: w } } @@ -255,26 +301,26 @@ impl Serializer { /// # assert!(bytes.is_empty()); /// ``` #[inline] - pub fn finalize(self) -> Vec { + pub fn finalize(self) -> &'a [u8] { self.data } #[inline] fn write_u8(&mut self, value: u8) -> Result<&mut Self> { - self.data.extend_from_slice(&[value][..]); + self.data.copy_from_slice(&[value][..]); Ok(self) } #[inline] fn write_u16(&mut self, value: u16) -> Result<&mut Self> { self.data - .extend_from_slice(&[((value & 0xFF_00) >> 8) as u8, (value & 0x00_FF) as u8][..]); + .copy_from_slice(&[((value & 0xFF_00) >> 8) as u8, (value & 0x00_FF) as u8][..]); Ok(self) } #[inline] fn write_u32(&mut self, value: u32) -> Result<&mut Self> { - self.data.extend_from_slice( + self.data.copy_from_slice( &[ ((value & 0xFF_00_00_00) >> 24) as u8, ((value & 0x00_FF_00_00) >> 16) as u8, @@ -287,7 +333,7 @@ impl Serializer { #[inline] fn write_u64(&mut self, value: u64) -> Result<&mut Self> { - self.data.extend_from_slice( + self.data.copy_from_slice( &[ ((value & 0xFF_00_00_00_00_00_00_00) >> 56) as u8, ((value & 0x00_FF_00_00_00_00_00_00) >> 48) as u8, @@ -304,7 +350,7 @@ impl Serializer { #[inline] fn write_f64(&mut self, value: f64) -> Result<&mut Self> { - self.data.extend_from_slice(&value.to_be_bytes()); + self.data.copy_from_slice(&value.to_be_bytes()); Ok(self) } @@ -423,7 +469,7 @@ impl Serializer { let bytes = bytes.as_ref(); self.write_type_definite(Type::Bytes, bytes.len() as u64, None) .map(|s| { - s.data.extend_from_slice(bytes); + s.data.copy_from_slice(bytes); s }) } @@ -441,7 +487,7 @@ impl Serializer { StringLenSz::Len(sz) => self .write_type_definite(Type::Bytes, bytes.len() as u64, Some(sz)) .map(|s| { - s.data.extend_from_slice(bytes); + s.data.copy_from_slice(bytes); s }), StringLenSz::Indefinite(lens) => { @@ -479,7 +525,7 @@ impl Serializer { let bytes = text.as_ref().as_bytes(); self.write_type_definite(Type::Text, bytes.len() as u64, None) .map(|s| { - s.data.extend_from_slice(bytes); + s.data.copy_from_slice(bytes); s }) } @@ -493,7 +539,7 @@ impl Serializer { StringLenSz::Len(sz) => self .write_type_definite(Type::Text, bytes.len() as u64, Some(sz)) .map(|s| { - s.data.extend_from_slice(bytes); + s.data.copy_from_slice(bytes); s }), StringLenSz::Indefinite(lens) => { @@ -710,7 +756,7 @@ impl Serializer { } /// Convenient member function to chain serialisation - pub fn serialize(&mut self, t: &T) -> Result<&mut Self> { + pub fn serialize(&'a mut self, t: &'a T) -> Result<&mut Self> { Serialize::serialize(t, self) } } @@ -722,9 +768,9 @@ macro_rules! serialize_array { $( impl Serialize for [T; $x] { fn serialize<'b>( - &self, - serializer: &'b mut Serializer, - ) -> Result<&'b mut Serializer> { + &'b self, + serializer: &'b mut Serializer<'b>, + ) -> Result<'b, &'b mut Serializer<'b>> { serialize_fixed_array(self.iter(), serializer) } } @@ -998,7 +1044,7 @@ mod test { // also make an indefinite encoded one out all the definite-encoded parts expected_bytes.push(0x5F); for slice in def_parts.iter() { - expected_bytes.extend_from_slice(&slice[..]); + expected_bytes.copy_from_slice(&slice[..]); } expected_bytes.push(0xFF); let indef_bytes = vec![ @@ -1047,7 +1093,7 @@ mod test { // also make an indefinite encoded one out all the definite-encoded parts expected_bytes.push(0x7F); for slice in def_parts.iter() { - expected_bytes.extend_from_slice(&slice[..]); + expected_bytes.copy_from_slice(&slice[..]); } expected_bytes.push(0xFF); let indef_lens = [ diff --git a/src/types.rs b/src/types.rs index ef9b586..f7d9426 100644 --- a/src/types.rs +++ b/src/types.rs @@ -68,9 +68,9 @@ pub enum Special { } impl Special { #[inline] - pub fn unwrap_bool(&self) -> Result<&bool> { + pub fn unwrap_bool(&self) -> Result { match self { - Special::Bool(b) => Ok(b), + Special::Bool(b) => Ok(*b), _ => Err(Error::CustomError( format_args!("Expected Special::Bool, received {:?}", self) .as_str() @@ -104,9 +104,9 @@ impl Special { } #[inline] - pub fn unwrap_unassigned(&self) -> Result<&u8> { + pub fn unwrap_unassigned(&self) -> Result { match self { - Special::Unassigned(v) => Ok(v), + Special::Unassigned(v) => Ok(*v), _ => Err(Error::CustomError( format_args!("Expected Special::Unassigned, received {:?}", self) .as_str() @@ -116,9 +116,9 @@ impl Special { } #[inline] - pub fn unwrap_float(&self) -> Result<&f64> { + pub fn unwrap_float(&self) -> Result { match self { - Special::Float(f) => Ok(f), + Special::Float(f) => Ok(*f), _ => Err(Error::CustomError( format_args!("Expected Special::Float, received {:?}", self) .as_str() diff --git a/src/value.rs b/src/value.rs index ff3af94..3600641 100644 --- a/src/value.rs +++ b/src/value.rs @@ -41,7 +41,10 @@ impl<'a> ObjectKey<'a> { } } impl<'a> Serialize for ObjectKey<'a> { - fn serialize<'se>(&self, serializer: &'se mut Serializer) -> Result<&'se mut Serializer> { + fn serialize<'se>( + &self, + serializer: &'se mut Serializer<'se>, + ) -> Result<'se, &'se mut Serializer<'se>> { match self { ObjectKey::Integer(ref v) => serializer.write_unsigned_integer(*v), ObjectKey::Bytes(ref v) => serializer.write_bytes(v), @@ -49,7 +52,7 @@ impl<'a> Serialize for ObjectKey<'a> { } } } -impl<'a> Deserialize<'a> for ObjectKey<'_> { +impl<'a> Deserialize<'a> for ObjectKey<'a> { fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { match raw.cbor_type()? { Type::UnsignedInteger => Ok(ObjectKey::Integer(raw.unsigned_integer()?)), @@ -82,32 +85,35 @@ pub enum Value<'a> { Object(BTreeMap, Value<'a>>), #[cfg(feature = "alloc")] IObject(BTreeMap, Value<'a>>), - #[cfg(feature = "alloc")] - Tag(u64, Box>), + Tag(u64, &'a Value<'a>), Special(Special), } impl Serialize for Value<'_> { - fn serialize<'se>(&self, serializer: &'se mut Serializer) -> Result<&'se mut Serializer> { + fn serialize<'se>( + &'se self, + serializer: &'se mut Serializer<'se>, + ) -> Result<'se, &'se mut Serializer<'se>> { match self { Value::U64(ref v) => serializer.write_unsigned_integer(*v), Value::I64(ref v) => serializer.write_negative_integer(*v), Value::Bytes(ref v) => serializer.write_bytes(v), Value::Text(ref v) => serializer.write_text(v), Value::Array(ref v) => { - serializer.write_array(Len::Len(v.len() as u64))?; + let mut s = serializer.write_array(Len::Len(v.len() as u64))?; for element in v.iter() { - serializer.serialize(element)?; + s = s.serialize(element)?; } - Ok(serializer) + Ok(s) } Value::IArray(ref v) => { - serializer.write_array(Len::Indefinite)?; + let mut s = serializer.write_array(Len::Indefinite)?; for element in v.iter() { - serializer.serialize(element)?; + s = s.serialize(element)?; } - serializer.write_special(Special::Break) + s.write_special(Special::Break) } + #[cfg(feature = "alloc")] Value::Object(ref v) => { serializer.write_map(Len::Len(v.len() as u64))?; for element in v { @@ -115,6 +121,7 @@ impl Serialize for Value<'_> { } Ok(serializer) } + #[cfg(feature = "alloc")] Value::IObject(ref v) => { serializer.write_map(Len::Indefinite)?; for element in v { @@ -122,7 +129,7 @@ impl Serialize for Value<'_> { } serializer.write_special(Special::Break) } - Value::Tag(ref tag, ref v) => serializer.write_tag(*tag)?.serialize(v.as_ref()), + Value::Tag(ref tag, ref v) => serializer.write_tag(*tag)?.serialize(v), Value::Special(ref v) => serializer.write_special(*v), } } @@ -160,6 +167,7 @@ impl<'a> Deserialize<'a> for Value<'_> { } } } + #[cfg(feature = "alloc")] Type::Map => { let len = raw.map()?; let mut vec = BTreeMap::new(); @@ -192,7 +200,7 @@ impl<'a> Deserialize<'a> for Value<'_> { } Type::Tag => { let tag = raw.tag()?; - Ok(Value::Tag(tag, Box::new(Deserialize::deserialize(raw)?))) + Ok(Value::Tag(tag, &Deserialize::deserialize(raw)?)) } Type::Special => Ok(Value::Special(raw.special()?)), } From a2c8bb0f8c95faddda1efa8ca146f04aa57d9acc Mon Sep 17 00:00:00 2001 From: SimonIT Date: Sat, 16 Mar 2024 23:17:31 +0100 Subject: [PATCH 03/11] Write to the correct position in serializer --- src/se.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/se.rs b/src/se.rs index b2abd31..7eb3632 100644 --- a/src/se.rs +++ b/src/se.rs @@ -258,6 +258,7 @@ const DEFAULT_CAPACITY: usize = 512; #[derive(Debug)] pub struct Serializer<'a> { data: &'a mut [u8], + pos: usize, } impl<'a> Serializer<'a> { @@ -267,7 +268,8 @@ impl<'a> Serializer<'a> { /// to add already CBOR encoded data or to add any bytes that may suite /// your protocol. pub fn write_raw_bytes(&mut self, bytes: &[u8]) -> Result<&mut Self> { - self.data.copy_from_slice(bytes); + self.data[self.pos..self.pos + bytes.len()].copy_from_slice(bytes); + self.pos += bytes.len(); Ok(self) } @@ -286,7 +288,7 @@ impl<'a> Serializer<'a> { #[inline] pub fn new(w: &'a mut [u8]) -> Self { - Serializer { data: w } + Serializer { data: w, pos: 0 } } /// finalize the serializer, returning the serializer bytes @@ -307,33 +309,29 @@ impl<'a> Serializer<'a> { #[inline] fn write_u8(&mut self, value: u8) -> Result<&mut Self> { - self.data.copy_from_slice(&[value][..]); - Ok(self) + self.write_raw_bytes(&[value][..]) } #[inline] fn write_u16(&mut self, value: u16) -> Result<&mut Self> { - self.data - .copy_from_slice(&[((value & 0xFF_00) >> 8) as u8, (value & 0x00_FF) as u8][..]); - Ok(self) + self.write_raw_bytes(&[((value & 0xFF_00) >> 8) as u8, (value & 0x00_FF) as u8][..]) } #[inline] fn write_u32(&mut self, value: u32) -> Result<&mut Self> { - self.data.copy_from_slice( + self.write_raw_bytes( &[ ((value & 0xFF_00_00_00) >> 24) as u8, ((value & 0x00_FF_00_00) >> 16) as u8, ((value & 0x00_00_FF_00) >> 8) as u8, (value & 0x00_00_00_FF) as u8, ][..], - ); - Ok(self) + ) } #[inline] fn write_u64(&mut self, value: u64) -> Result<&mut Self> { - self.data.copy_from_slice( + self.write_raw_bytes( &[ ((value & 0xFF_00_00_00_00_00_00_00) >> 56) as u8, ((value & 0x00_FF_00_00_00_00_00_00) >> 48) as u8, @@ -344,14 +342,12 @@ impl<'a> Serializer<'a> { ((value & 0x00_00_00_00_00_00_FF_00) >> 8) as u8, (value & 0x00_00_00_00_00_00_00_FF) as u8, ][..], - ); - Ok(self) + ) } #[inline] fn write_f64(&mut self, value: f64) -> Result<&mut Self> { - self.data.copy_from_slice(&value.to_be_bytes()); - Ok(self) + self.write_raw_bytes(&value.to_be_bytes()) } /// Writes a CBOR type with the extra `len` information From ea1ebc68a2a43056b6c1ca00216d98fa8ecfb714 Mon Sep 17 00:00:00 2001 From: SimonIT Date: Thu, 21 Mar 2024 23:26:18 +0100 Subject: [PATCH 04/11] Introduce allocation functions --- src/de.rs | 150 ++++++++++++++++++++++++++++++++++++++------------- src/error.rs | 3 ++ src/len.rs | 4 +- src/lib.rs | 1 + src/se.rs | 49 ++++++++++------- src/types.rs | 49 +++++++++-------- src/value.rs | 9 ++-- 7 files changed, 183 insertions(+), 82 deletions(-) diff --git a/src/de.rs b/src/de.rs index 5baeca9..1474af7 100644 --- a/src/de.rs +++ b/src/de.rs @@ -189,6 +189,7 @@ impl<'a, T: Deserialize<'a>> Deserialize<'a> for Option { pub struct Deserializer<'a> { data: &'a [u8], pos: usize, + allocate: Option &'a mut [u8]>, } #[cfg(feature = "alloc")] @@ -197,13 +198,18 @@ impl From> for Deserializer { Deserializer { data: r.as_slice(), pos: 0, + allocate: Some(move |len| Vec::with_capacity(len).as_mut_slice()), } } } impl<'a> From<&'a [u8]> for Deserializer<'a> { fn from(r: &'a [u8]) -> Self { - Deserializer { data: r, pos: 0 } + Deserializer { + data: r, + pos: 0, + allocate: None, + } } } @@ -366,8 +372,7 @@ impl<'a> Deserializer<'a> { } } - /// consume the given `len` from the underlying buffer. Skipped bytes are - /// then lost, they cannot be retrieved for future references. + /// consume the given `len` from the underlying buffer #[inline] pub fn advance(&mut self, len: usize) -> Result<'a, ()> { self.pos += len; @@ -480,20 +485,49 @@ impl<'a> Deserializer<'a> { /// let bytes = raw.bytes().unwrap(); /// ``` pub fn bytes(&mut self) -> Result<'a, &'a [u8]> { - Ok(self.bytes_sz()?.0) + Ok(self.bytes_sz(None)?.0) } /// Read a Bytes from the Deserializer with encoding information /// /// Same as `bytes` but also returns `StringLenSz` for details about the encoding used. - pub fn bytes_sz(&mut self) -> Result<'a, (&'a [u8], StringLenSz)> { + #[cfg(feature = "alloc")] + pub fn bytes_sz_vec(&mut self) -> Result<'a, (&'a [u8], StringLenSz)> { + self.bytes_sz(Some(|len| Vec::with_capacity(len).as_mut_slice())) + } + + pub fn bytes_sz( + &mut self, + sz_alloc: Option &'a mut [(u64, Sz)]>, + ) -> Result<'a, (&'a [u8], StringLenSz)> { self.cbor_expect_type(Type::Bytes)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; match len_sz { LenSz::Indefinite => { - let mut bytes: &[u8] = *[]; - let mut chunk_lens: [(u64, Sz)] = *[]; + if self.allocate.is_none() { + return Err(Error::NoAllocator); + } + let start = self.pos; + let mut chunks = 0; + while self.cbor_type()? != Type::Special || !self.special_break()? { + self.cbor_expect_type(Type::Bytes)?; + let chunk_len_sz = self.cbor_len_sz()?; + match chunk_len_sz { + LenSz::Indefinite => return Err(Error::InvalidIndefiniteString), + LenSz::Len(len, sz) => { + self.advance(1 + sz.bytes_following())?; + self.advance(len as usize)?; + chunks += 1; + } + } + } + let size = self.pos - start; + self.pos -= size; + let bytes = self.allocate.unwrap()(size); + let mut array_pos: usize = 0; + let mut chunk_pos: usize = 0; + let mut chunk_lens = sz_alloc.map(|f| f(chunks)); while self.cbor_type()? != Type::Special || !self.special_break()? { self.cbor_expect_type(Type::Bytes)?; let chunk_len_sz = self.cbor_len_sz()?; @@ -501,14 +535,21 @@ impl<'a> Deserializer<'a> { LenSz::Indefinite => return Err(Error::InvalidIndefiniteString), LenSz::Len(len, sz) => { self.advance(1 + sz.bytes_following())?; - bytes = - &[bytes, &self.data[self.pos..self.pos + len as usize]].concat(); + bytes[array_pos..array_pos + len as usize] + .copy_from_slice(&self.data[self.pos..self.pos + len as usize]); + array_pos += len as usize; self.advance(len as usize)?; - chunk_lens = [chunk_lens, *[(len, sz)]].concat(); + if let Some(ref mut c) = chunk_lens { + c[chunk_pos..chunk_pos + 1].fill((len, sz)); + chunk_pos += 1; + } } } } - Ok((bytes, StringLenSz::Indefinite(chunk_lens))) + Ok(( + bytes, + StringLenSz::Indefinite(chunk_lens.unwrap_or(&mut [])), + )) } LenSz::Len(len, sz) => { let bytes = &self.data[self.pos..self.pos + len as usize]; @@ -535,20 +576,31 @@ impl<'a> Deserializer<'a> { /// assert!(&*text == "text"); /// ``` pub fn text(&mut self) -> Result<'a, &'a str> { - Ok(self.text_sz()?.0) + Ok(self.text_sz(None)?.0) } /// Read a Text from the Deserializer with encoding information /// /// Same as `text` but also returns `StringLenSz` for details about the encoding used. - pub fn text_sz(&mut self) -> Result<'a, (&'a str, StringLenSz)> { + #[cfg(feature = "alloc")] + pub fn text_sz_vec(&mut self) -> Result<'a, (&'a str, StringLenSz)> { + self.text_sz(Some(|len| Vec::with_capacity(len).as_mut_slice())) + } + + pub fn text_sz( + &mut self, + sz_alloc: Option &'a mut [(u64, Sz)]>, + ) -> Result<'a, (&'a str, StringLenSz)> { self.cbor_expect_type(Type::Text)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; match len_sz { LenSz::Indefinite => { - let mut text: [&str] = *[]; - let mut chunk_lens: [(u64, Sz)] = *[]; + if self.allocate.is_none() { + return Err(Error::NoAllocator); + } + let start = self.pos; + let mut chunks = 0; while self.cbor_type()? != Type::Special || !self.special_break()? { self.cbor_expect_type(Type::Text)?; let chunk_len = self.cbor_len_sz()?; @@ -558,15 +610,41 @@ impl<'a> Deserializer<'a> { // rfc7049 forbids splitting UTF-8 characters across chunks so we must // read each chunk separately as a definite encoded UTF-8 string self.advance(1 + sz.bytes_following())?; - let bytes = &self.data[self.pos..self.pos + len as usize]; - let chunk_text = core::str::from_utf8(bytes)?; self.advance(len as usize)?; - text.push_str(chunk_text); - chunk_lens.push((len, sz)); + chunks += 1; + } + } + } + let size = self.pos - start; + self.pos -= size; + let bytes = self.allocate.unwrap()(size); + let mut array_pos: usize = 0; + let mut chunk_pos: usize = 0; + let mut chunk_lens = sz_alloc.map(|f| f(chunks)); + while self.cbor_type()? != Type::Special || !self.special_break()? { + self.cbor_expect_type(Type::Text)?; + let chunk_len = self.cbor_len_sz()?; + match chunk_len { + LenSz::Indefinite => return Err(Error::InvalidIndefiniteString), + LenSz::Len(len, sz) => { + // rfc7049 forbids splitting UTF-8 characters across chunks so we must + // read each chunk separately as a definite encoded UTF-8 string + self.advance(1 + sz.bytes_following())?; + bytes[array_pos..array_pos + len as usize] + .copy_from_slice(&self.data[self.pos..self.pos + len as usize]); + array_pos += len as usize; + self.advance(len as usize)?; + if let Some(ref mut c) = chunk_lens { + c[chunk_pos..chunk_pos + 1].fill((len, sz)); + chunk_pos += 1; + } } } } - Ok((text, StringLenSz::Indefinite(chunk_lens))) + Ok(( + core::str::from_utf8(bytes)?, + StringLenSz::Indefinite(chunk_lens.unwrap_or(&mut [])), + )) } LenSz::Len(len, sz) => { let bytes = &self.data[self.pos..self.pos + len as usize]; @@ -1221,7 +1299,7 @@ mod test { 0xBA, 0xAD, 0xF0, 0x0D, 0xCA, 0xFE, 0xD0, 0x0D, 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBE, 0xEF, ]; - let indef_lens = vec![ + let indef_lens = &[ (4, Sz::Inline), (4, Sz::One), (4, Sz::Two), @@ -1229,28 +1307,28 @@ mod test { (2, Sz::Eight), ]; assert_eq!( - raw.bytes_sz().unwrap(), + raw.bytes_sz_vec().unwrap(), (vec![0xBA, 0xAD, 0xF0, 0x0D], StringLenSz::Len(Sz::Inline)) ); assert_eq!( - raw.bytes_sz().unwrap(), + raw.bytes_sz_vec().unwrap(), (vec![0xCA, 0xFE, 0xD0, 0x0D], StringLenSz::Len(Sz::One)) ); assert_eq!( - raw.bytes_sz().unwrap(), + raw.bytes_sz_vec().unwrap(), (vec![0xDE, 0xAD, 0xBE, 0xEF], StringLenSz::Len(Sz::Two)) ); assert_eq!( - raw.bytes_sz().unwrap(), + raw.bytes_sz_vec().unwrap(), (vec![0xCA, 0xFE], StringLenSz::Len(Sz::Four)) ); assert_eq!( - raw.bytes_sz().unwrap(), + raw.bytes_sz_vec().unwrap(), (vec![0xBE, 0xEF], StringLenSz::Len(Sz::Eight)) ); assert_eq!( - raw.bytes_sz().unwrap(), - (indef_bytes, StringLenSz::Indefinite(*indef_lens)) + raw.bytes_sz_vec().unwrap(), + (indef_bytes, StringLenSz::Indefinite(indef_lens)) ); } @@ -1275,7 +1353,7 @@ mod test { } vec.push(0xFF); let mut raw = Deserializer::from(vec); - let indef_lens = vec![ + let indef_lens = &[ (5, Sz::Inline), (5, Sz::One), (9, Sz::Two), @@ -1283,30 +1361,30 @@ mod test { (3, Sz::Eight), ]; assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz_vec().unwrap(), ("Hello".into(), StringLenSz::Len(Sz::Inline)) ); assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz_vec().unwrap(), ("World".into(), StringLenSz::Len(Sz::One)) ); assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz_vec().unwrap(), ("日本語".into(), StringLenSz::Len(Sz::Two)) ); assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz_vec().unwrap(), ("9".into(), StringLenSz::Len(Sz::Four)) ); assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz_vec().unwrap(), ("ABC".into(), StringLenSz::Len(Sz::Eight)) ); assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz_vec().unwrap(), ( "HelloWorld日本語9ABC".into(), - StringLenSz::Indefinite(*indef_lens) + StringLenSz::Indefinite(indef_lens) ) ); } diff --git a/src/error.rs b/src/error.rs index 6bcbffc..6482960 100644 --- a/src/error.rs +++ b/src/error.rs @@ -33,6 +33,8 @@ pub enum Error<'a> { InvalidLenPassed(len::Sz), InvalidNint(i128), + NoAllocator, + CustomError(&'a str), } impl From for Error<'_> { @@ -88,6 +90,7 @@ impl fmt::Display for Error<'_> { TrailingData => write!(f, "Unexpected trailing data in CBOR"), InvalidIndefiniteString => write!(f, "Invalid cbor: Invalid indefinite string format"), InvalidLenPassed(sz) => write!(f, "Invalid length for serialization: {:?}", sz), + NoAllocator => write!(f, "No allocator provided"), CustomError(err) => write!(f, "Invalid cbor: {}", err), InvalidNint(x) => write!(f, "Passed nint {} out of range", x), } diff --git a/src/len.rs b/src/len.rs index 2637338..89dbbb6 100644 --- a/src/len.rs +++ b/src/len.rs @@ -90,7 +90,7 @@ impl LenSz { /// the length e.g. 4 can be represented inline in the type, or in 1/2/4/8 /// additional bytes #[derive(Debug, PartialEq, Eq)] -pub enum StringLenSz { - Indefinite([(u64, Sz)]), +pub enum StringLenSz<'a> { + Indefinite(&'a [(u64, Sz)]), Len(Sz), } diff --git a/src/lib.rs b/src/lib.rs index 5b1fc3b..51ebe22 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,6 +62,7 @@ #[cfg(test)] #[macro_use] extern crate quickcheck; +#[cfg(any(feature = "alloc", test))] extern crate alloc; pub mod de; diff --git a/src/se.rs b/src/se.rs index 7eb3632..2d98c39 100644 --- a/src/se.rs +++ b/src/se.rs @@ -1,5 +1,7 @@ //! CBOR serialisation tooling +#[cfg(feature = "alloc")] use alloc::string::String; +#[cfg(feature = "alloc")] use alloc::vec::Vec; use core::convert::TryInto; @@ -78,6 +80,7 @@ impl Serialize for f64 { serializer.write_special(Special::Float(*self)) } } +#[cfg(feature = "alloc")] impl Serialize for String { fn serialize<'a>( &self, @@ -234,14 +237,30 @@ where /// serializer.write_bytes(&se.finalize()).unwrap(); /// ``` /// -pub fn serialize_cbor_in_cbor<'a, T>( +#[cfg(feature = "alloc")] +pub fn serialize_cbor_in_cbor_vec<'a, T>( data: T, serializer: &'a mut Serializer<'a>, ) -> Result<'a, &'a mut Serializer<'a>> where T: Serialize, { - let mut se = Serializer::new_vec(); + serialize_cbor_in_cbor( + data, + serializer, + Vec::with_capacity(DEFAULT_CAPACITY).as_mut_slice(), + ) +} + +pub fn serialize_cbor_in_cbor<'a, T>( + data: T, + serializer: &'a mut Serializer<'a>, + buffer: &'a mut [u8], +) -> Result<'a, &'a mut Serializer<'a>> +where + T: Serialize + 'a, +{ + let mut se = Serializer::new(buffer); data.serialize(&mut se)?; serializer.write_bytes(&se.finalize()) } @@ -465,7 +484,7 @@ impl<'a> Serializer<'a> { let bytes = bytes.as_ref(); self.write_type_definite(Type::Bytes, bytes.len() as u64, None) .map(|s| { - s.data.copy_from_slice(bytes); + s.write_raw_bytes(bytes).unwrap(); s }) } @@ -483,7 +502,7 @@ impl<'a> Serializer<'a> { StringLenSz::Len(sz) => self .write_type_definite(Type::Bytes, bytes.len() as u64, Some(sz)) .map(|s| { - s.data.copy_from_slice(bytes); + s.write_raw_bytes(bytes).unwrap(); s }), StringLenSz::Indefinite(lens) => { @@ -494,9 +513,9 @@ impl<'a> Serializer<'a> { self.write_u8(Type::Bytes.to_byte(0x1f))?; let mut start = 0; for (len, sz) in lens { - let end = start + len as usize; + let end = start + *len as usize; let chunk = &bytes[start..end]; - self.write_bytes_sz(chunk, StringLenSz::Len(sz))?; + self.write_bytes_sz(chunk, StringLenSz::Len(*sz))?; start = end; } self.write_u8(Type::Special.to_byte(0x1f))?; @@ -520,10 +539,7 @@ impl<'a> Serializer<'a> { pub fn write_text>(&mut self, text: S) -> Result<&mut Self> { let bytes = text.as_ref().as_bytes(); self.write_type_definite(Type::Text, bytes.len() as u64, None) - .map(|s| { - s.data.copy_from_slice(bytes); - s - }) + .map(|s| s.write_raw_bytes(bytes).unwrap()) } /// write the given object as text using a specific string encoding @@ -534,10 +550,7 @@ impl<'a> Serializer<'a> { match sz { StringLenSz::Len(sz) => self .write_type_definite(Type::Text, bytes.len() as u64, Some(sz)) - .map(|s| { - s.data.copy_from_slice(bytes); - s - }), + .map(|s| s.write_raw_bytes(bytes).unwrap()), StringLenSz::Indefinite(lens) => { let sz_sum = lens.iter().fold(0, |sum, len| sum + len.0); if sz_sum != bytes.len() as u64 { @@ -546,11 +559,11 @@ impl<'a> Serializer<'a> { self.write_u8(Type::Text.to_byte(0x1f))?; let mut start = 0; for (len, sz) in lens { - let end = start + len as usize; + let end = start + *len as usize; let chunk = &bytes[start..end]; - let chunk_str = String::from_utf8(chunk.to_vec()) - .map_err(|_| Error::InvalidLenPassed(sz))?; - self.write_text_sz(chunk_str, StringLenSz::Len(sz))?; + let chunk_str = + core::str::from_utf8(chunk).map_err(|_| Error::InvalidLenPassed(*sz))?; + self.write_text_sz(chunk_str, StringLenSz::Len(*sz))?; start = end; } self.write_u8(Type::Special.to_byte(0x1f))?; diff --git a/src/types.rs b/src/types.rs index f7d9426..21a3b77 100644 --- a/src/types.rs +++ b/src/types.rs @@ -31,7 +31,7 @@ impl Type { Type::Special => 0b1110_0000, } } - pub fn from_byte(byte: u8) -> Type { + pub fn from_byte(byte: &u8) -> Type { match byte & 0b1110_0000 { 0b0000_0000 => Type::UnsignedInteger, 0b0010_0000 => Type::NegativeInteger, @@ -45,8 +45,8 @@ impl Type { } } } -impl From for Type { - fn from(byte: u8) -> Type { +impl From<&u8> for Type { + fn from(byte: &u8) -> Type { Type::from_byte(byte) } } @@ -68,9 +68,9 @@ pub enum Special { } impl Special { #[inline] - pub fn unwrap_bool(&self) -> Result { + pub fn unwrap_bool(self) -> Result<'static, bool> { match self { - Special::Bool(b) => Ok(*b), + Special::Bool(b) => Ok(b), _ => Err(Error::CustomError( format_args!("Expected Special::Bool, received {:?}", self) .as_str() @@ -80,7 +80,7 @@ impl Special { } #[inline] - pub fn unwrap_null(&self) -> Result<()> { + pub fn unwrap_null(self) -> Result<'static, ()> { match self { Special::Null => Ok(()), _ => Err(Error::CustomError( @@ -92,7 +92,7 @@ impl Special { } #[inline] - pub fn unwrap_undefined(&self) -> Result<()> { + pub fn unwrap_undefined(self) -> Result<'static, ()> { match self { Special::Undefined => Ok(()), _ => Err(Error::CustomError( @@ -104,9 +104,9 @@ impl Special { } #[inline] - pub fn unwrap_unassigned(&self) -> Result { + pub fn unwrap_unassigned(self) -> Result<'static, u8> { match self { - Special::Unassigned(v) => Ok(*v), + Special::Unassigned(v) => Ok(v), _ => Err(Error::CustomError( format_args!("Expected Special::Unassigned, received {:?}", self) .as_str() @@ -116,9 +116,9 @@ impl Special { } #[inline] - pub fn unwrap_float(&self) -> Result { + pub fn unwrap_float(self) -> Result<'static, f64> { match self { - Special::Float(f) => Ok(*f), + Special::Float(f) => Ok(f), _ => Err(Error::CustomError( format_args!("Expected Special::Float, received {:?}", self) .as_str() @@ -128,7 +128,7 @@ impl Special { } #[inline] - pub fn unwrap_break(&self) -> Result<()> { + pub fn unwrap_break(self) -> Result<'static, ()> { match self { Special::Break => Ok(()), _ => Err(Error::CustomError( @@ -162,18 +162,23 @@ mod tests { #[test] fn major_type_byte_encoding() { for i in 0b0000_0000..=0b0001_1111 { - assert!( - Type::UnsignedInteger == Type::from_byte(Type::to_byte(Type::UnsignedInteger, i)) + assert_eq!( + Type::UnsignedInteger, + Type::from_byte(&Type::to_byte(Type::UnsignedInteger, i)) ); - assert!( - Type::NegativeInteger == Type::from_byte(Type::to_byte(Type::NegativeInteger, i)) + assert_eq!( + Type::NegativeInteger, + Type::from_byte(&Type::to_byte(Type::NegativeInteger, i)) + ); + assert_eq!(Type::Bytes, Type::from_byte(&Type::to_byte(Type::Bytes, i))); + assert_eq!(Type::Text, Type::from_byte(&Type::to_byte(Type::Text, i))); + assert_eq!(Type::Array, Type::from_byte(&Type::to_byte(Type::Array, i))); + assert_eq!(Type::Map, Type::from_byte(&Type::to_byte(Type::Map, i))); + assert_eq!(Type::Tag, Type::from_byte(&Type::to_byte(Type::Tag, i))); + assert_eq!( + Type::Special, + Type::from_byte(&Type::to_byte(Type::Special, i)) ); - assert!(Type::Bytes == Type::from_byte(Type::to_byte(Type::Bytes, i))); - assert!(Type::Text == Type::from_byte(Type::to_byte(Type::Text, i))); - assert!(Type::Array == Type::from_byte(Type::to_byte(Type::Array, i))); - assert!(Type::Map == Type::from_byte(Type::to_byte(Type::Map, i))); - assert!(Type::Tag == Type::from_byte(Type::to_byte(Type::Tag, i))); - assert!(Type::Special == Type::from_byte(Type::to_byte(Type::Special, i))); } } } diff --git a/src/value.rs b/src/value.rs index 3600641..c174197 100644 --- a/src/value.rs +++ b/src/value.rs @@ -9,6 +9,8 @@ //! //! This is why all the objects here are marked as deprecated +#[cfg(feature = "alloc")] +use alloc::collections::BTreeMap; #[cfg(test)] use core::iter::repeat_with; @@ -362,12 +364,11 @@ mod test { ); } - #[cfg(feature = "alloc")] #[test] fn tag() { - assert!(test_encode_decode(&Value::Tag(23, Box::new(Value::U64(0)))).unwrap()); - assert!(test_encode_decode(&Value::Tag(24, Box::new(Value::Bytes(&[0; 32])))).unwrap()); - assert!(test_encode_decode(&Value::Tag(0x1ff, Box::new(Value::Bytes(&[0; 624])))).unwrap()); + assert!(test_encode_decode(&Value::Tag(23, &Value::U64(0))).unwrap()); + assert!(test_encode_decode(&Value::Tag(24, &Value::Bytes(&[0; 32]))).unwrap()); + assert!(test_encode_decode(&Value::Tag(0x1ff, &Value::Bytes(&[0; 624]))).unwrap()); } quickcheck! { From 8b2ebc68814f8561e27a1d7cf98022e4b2c2a72d Mon Sep 17 00:00:00 2001 From: SimonIT Date: Sat, 23 Mar 2024 20:53:48 +0100 Subject: [PATCH 05/11] ValueArrayIter --- src/de.rs | 15 ++++++ src/value.rs | 144 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 143 insertions(+), 16 deletions(-) diff --git a/src/de.rs b/src/de.rs index 1474af7..db457ac 100644 --- a/src/de.rs +++ b/src/de.rs @@ -380,6 +380,21 @@ impl<'a> Deserializer<'a> { Ok(()) } + #[inline] + pub fn position(&self) -> usize { + self.pos + } + + #[inline] + pub fn seek(&mut self, pos: usize) -> Result<'a, ()> { + if pos > self.data.len() { + Err(Error::NotEnough(self.data.len(), pos)) + } else { + self.pos = pos; + Ok(()) + } + } + /// Read an `UnsignedInteger` from the `Deserializer` /// /// The function fails if the type of the given Deserializer is not `Type::UnsignedInteger`. diff --git a/src/value.rs b/src/value.rs index c174197..ce74847 100644 --- a/src/value.rs +++ b/src/value.rs @@ -11,6 +11,7 @@ #[cfg(feature = "alloc")] use alloc::collections::BTreeMap; +use core::fmt::Debug; #[cfg(test)] use core::iter::repeat_with; @@ -81,8 +82,8 @@ pub enum Value<'a> { I64(i64), Bytes(&'a [u8]), Text(&'a str), - Array(&'a [Value<'a>]), - IArray(&'a [Value<'a>]), + Array(ValueArrayIter<'a>), + IArray(ValueArrayIter<'a>), #[cfg(feature = "alloc")] Object(BTreeMap, Value<'a>>), #[cfg(feature = "alloc")] @@ -103,15 +104,15 @@ impl Serialize for Value<'_> { Value::Text(ref v) => serializer.write_text(v), Value::Array(ref v) => { let mut s = serializer.write_array(Len::Len(v.len() as u64))?; - for element in v.iter() { - s = s.serialize(element)?; + for element in v.into_iter() { + s = s.serialize(&element)?; } Ok(s) } - Value::IArray(ref v) => { + Value::IArray(v) => { let mut s = serializer.write_array(Len::Indefinite)?; - for element in v.iter() { - s = s.serialize(element)?; + for element in v.into_iter() { + s = s.serialize(&element)?; } s.write_special(Special::Break) } @@ -145,9 +146,10 @@ impl<'a> Deserialize<'a> for Value<'_> { Type::Text => Ok(Value::Text(raw.text()?)), Type::Array => { let len = raw.array()?; - let mut vec = Vec::new(); match len { Len::Indefinite => { + let mut item_count = 0; + let start = raw.position(); while { let t = raw.cbor_type()?; if t == Type::Special { @@ -155,18 +157,19 @@ impl<'a> Deserialize<'a> for Value<'_> { assert_eq!(special, Special::Break); false } else { - vec.push(Deserialize::deserialize(raw)?); + Deserialize::deserialize(raw)?; + item_count += 1; true } } {} - Ok(Value::IArray(vec)) - } - Len::Len(len) => { - for _ in 0..len { - vec.push(Deserialize::deserialize(raw)?); - } - Ok(Value::Array(vec)) + raw.seek(start)?; + Ok(Value::IArray(ValueArrayIter::new(raw, len, item_count))) } + Len::Len(item_count) => Ok(Value::Array(ValueArrayIter::new( + raw, + len, + item_count as usize, + ))), } } #[cfg(feature = "alloc")] @@ -209,6 +212,115 @@ impl<'a> Deserialize<'a> for Value<'_> { } } +struct ValueArrayIter<'a> { + raw: &'a mut Deserializer<'static>, + len: Len, + item_number: usize, + start_pos: usize, + iteration_pos: usize, + iterated_item_number: usize, +} + +impl Clone for ValueArrayIter<'_> { + fn clone(&self) -> Self { + ValueArrayIter { + raw: self.raw, + len: self.len, + item_number: self.item_number, + start_pos: self.start_pos, + iteration_pos: self.iteration_pos, + iterated_item_number: self.iterated_item_number, + } + } +} + +impl Debug for ValueArrayIter<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_list().entries(self.clone()).finish() + } +} + +impl PartialEq for ValueArrayIter<'_> { + fn eq(&self, other: &Self) -> bool { + if self.len() != other.len() { + return false; + } + let mut me = self.clone(); + let mut other = other.clone(); + (0..self.len()) + .into_iter() + .map(|i| me.next().unwrap().eq(&other.next().unwrap())) + .all(|x| x) + } +} + +impl PartialOrd for ValueArrayIter<'_> { + fn partial_cmp(&self, other: &Self) -> Option { + if self.len() != other.len() { + return None; + } + let mut me = self.clone(); + let mut other = other.clone(); + (0..self.len()) + .into_iter() + .map(|i| me.next().unwrap().partial_cmp(&other.next().unwrap())) + .fold(Some(core::cmp::Ordering::Equal), |acc, x| { + if acc == Some(core::cmp::Ordering::Equal) { + x + } else { + acc + } + }) + } +} + +impl<'a> ValueArrayIter<'_> { + fn new(raw: &'a mut Deserializer<'static>, len: Len, item_number: usize) -> Self { + ValueArrayIter { + raw, + len, + item_number, + start_pos: raw.position(), + iteration_pos: raw.position(), + iterated_item_number: 0, + } + } + + fn len(&self) -> usize { + self.item_number + } +} + +impl Iterator for ValueArrayIter<'_> { + type Item = Value<'static>; + + fn next(&mut self) -> Option { + // Save deserializer position + let iterate_pos = self.raw.position(); + // Goto array items position + self.raw.seek(self.iteration_pos).unwrap(); + let val = if self.iterated_item_number >= self.item_number { + if self.len == Len::Indefinite { + let t = self.raw.cbor_type().unwrap(); + if t == Type::Special { + let special = self.raw.special().unwrap(); + assert_eq!(special, Special::Break); + } + } + None + } else { + Some(Deserialize::deserialize(self.raw).unwrap()) + }; + // Count iterated items + self.iterated_item_number += 1; + // Save current item position for next item + self.iteration_pos = self.raw.position(); + // Restore deserializer position + self.raw.seek(iterate_pos).unwrap(); + val + } +} + #[cfg(test)] impl Arbitrary for ObjectKey { fn arbitrary(g: &mut G) -> Self { From e5df5c73305a57dae677afb944c3869f134efc65 Mon Sep 17 00:00:00 2001 From: SimonIT Date: Mon, 25 Mar 2024 19:23:22 +0100 Subject: [PATCH 06/11] refactor to reference buffer and not dese --- src/value.rs | 204 ++++++++++++++++++++++++++------------------------- 1 file changed, 106 insertions(+), 98 deletions(-) diff --git a/src/value.rs b/src/value.rs index ce74847..6b5ab7b 100644 --- a/src/value.rs +++ b/src/value.rs @@ -14,6 +14,8 @@ use alloc::collections::BTreeMap; use core::fmt::Debug; #[cfg(test)] use core::iter::repeat_with; +use core::iter::FromIterator; +use core::result::IntoIter; #[cfg(test)] use quickcheck::{Arbitrary, Gen}; @@ -24,6 +26,7 @@ use len::Len; use result::Result; use se::*; use types::{Special, Type}; +use value::ValueArrayIter::DE; /// CBOR Object key, represents the possible supported values for /// a CBOR key in a CBOR Map. @@ -103,15 +106,15 @@ impl Serialize for Value<'_> { Value::Bytes(ref v) => serializer.write_bytes(v), Value::Text(ref v) => serializer.write_text(v), Value::Array(ref v) => { - let mut s = serializer.write_array(Len::Len(v.len() as u64))?; - for element in v.into_iter() { + let mut s = serializer.write_array(Len::Len(v.clone().count() as u64))?; + for element in v.clone().into_iter() { s = s.serialize(&element)?; } Ok(s) } Value::IArray(v) => { let mut s = serializer.write_array(Len::Indefinite)?; - for element in v.into_iter() { + for element in v.clone().into_iter() { s = s.serialize(&element)?; } s.write_special(Special::Break) @@ -148,7 +151,6 @@ impl<'a> Deserialize<'a> for Value<'_> { let len = raw.array()?; match len { Len::Indefinite => { - let mut item_count = 0; let start = raw.position(); while { let t = raw.cbor_type()?; @@ -157,51 +159,64 @@ impl<'a> Deserialize<'a> for Value<'_> { assert_eq!(special, Special::Break); false } else { - Deserialize::deserialize(raw)?; - item_count += 1; + Value::deserialize(raw)?; true } } {} - raw.seek(start)?; - Ok(Value::IArray(ValueArrayIter::new(raw, len, item_count))) + Ok(Value::IArray(ValueArrayIter::new( + &raw.inner()[start..raw.position()], + len, + ))) + } + Len::Len(item_count) => { + let start = raw.position(); + (0..item_count).for_each(|_| { + Value::deserialize(raw); + }); + Ok(Value::Array(ValueArrayIter::new( + &raw.inner()[start..raw.position()], + len, + ))) } - Len::Len(item_count) => Ok(Value::Array(ValueArrayIter::new( - raw, - len, - item_count as usize, - ))), } } - #[cfg(feature = "alloc")] Type::Map => { - let len = raw.map()?; - let mut vec = BTreeMap::new(); - match len { - Len::Indefinite => { - while { - let t = raw.cbor_type()?; - if t == Type::Special { - let special = raw.special()?; - assert_eq!(special, Special::Break); - false - } else { + #[cfg(feature = "alloc")] + { + let len = raw.map()?; + let mut vec = BTreeMap::new(); + match len { + Len::Indefinite => { + while { + let t = raw.cbor_type()?; + if t == Type::Special { + let special = raw.special()?; + assert_eq!(special, Special::Break); + false + } else { + let k = Deserialize::deserialize(raw)?; + let v = Deserialize::deserialize(raw)?; + vec.insert(k, v); + true + } + } {} + Ok(Value::IObject(vec)) + } + Len::Len(len) => { + for _ in 0..len { let k = Deserialize::deserialize(raw)?; let v = Deserialize::deserialize(raw)?; vec.insert(k, v); - true } - } {} - Ok(Value::IObject(vec)) - } - Len::Len(len) => { - for _ in 0..len { - let k = Deserialize::deserialize(raw)?; - let v = Deserialize::deserialize(raw)?; - vec.insert(k, v); + Ok(Value::Object(vec)) } - Ok(Value::Object(vec)) } } + + #[cfg(not(feature = "alloc"))] + { + Err(Error::NoAllocator) + } } Type::Tag => { let tag = raw.tag()?; @@ -212,25 +227,34 @@ impl<'a> Deserialize<'a> for Value<'_> { } } -struct ValueArrayIter<'a> { - raw: &'a mut Deserializer<'static>, +enum ValueArrayIter<'a> { + SE(&'a IntoIter>), + DE(DeValueArrayIter<'a>), +} + +impl<'a> ValueArrayIter<'a> { + fn new(data: &'a [u8], len: Len) -> Self { + DE(DeValueArrayIter::new(data, len)) + } +} + +impl<'a> FromIterator> for ValueArrayIter<'a> { + fn from_iter, IntoIter = &'a IntoIter>>>( + iter: T, + ) -> Self { + ValueArrayIter::SE(iter.into_iter()) + } +} + +struct DeValueArrayIter<'a> { + raw: &'a mut Deserializer<'a>, len: Len, - item_number: usize, - start_pos: usize, - iteration_pos: usize, iterated_item_number: usize, } impl Clone for ValueArrayIter<'_> { fn clone(&self) -> Self { - ValueArrayIter { - raw: self.raw, - len: self.len, - item_number: self.item_number, - start_pos: self.start_pos, - iteration_pos: self.iteration_pos, - iterated_item_number: self.iterated_item_number, - } + todo!() } } @@ -242,28 +266,23 @@ impl Debug for ValueArrayIter<'_> { impl PartialEq for ValueArrayIter<'_> { fn eq(&self, other: &Self) -> bool { - if self.len() != other.len() { - return false; - } - let mut me = self.clone(); + let me = self.clone(); let mut other = other.clone(); - (0..self.len()) - .into_iter() - .map(|i| me.next().unwrap().eq(&other.next().unwrap())) - .all(|x| x) + for i in me.into_iter() { + if i != other.next().unwrap() { + return false; + } + } + true } } impl PartialOrd for ValueArrayIter<'_> { fn partial_cmp(&self, other: &Self) -> Option { - if self.len() != other.len() { - return None; - } - let mut me = self.clone(); + let me = self.clone(); let mut other = other.clone(); - (0..self.len()) - .into_iter() - .map(|i| me.next().unwrap().partial_cmp(&other.next().unwrap())) + me.into_iter() + .map(|i| i.partial_cmp(&other.next().unwrap())) .fold(Some(core::cmp::Ordering::Equal), |acc, x| { if acc == Some(core::cmp::Ordering::Equal) { x @@ -274,50 +293,39 @@ impl PartialOrd for ValueArrayIter<'_> { } } -impl<'a> ValueArrayIter<'_> { - fn new(raw: &'a mut Deserializer<'static>, len: Len, item_number: usize) -> Self { - ValueArrayIter { - raw, +impl<'a> DeValueArrayIter<'a> { + fn new(data: &'a [u8], len: Len) -> Self { + let mut raw = Deserializer::from(data); + DeValueArrayIter { + raw: &mut raw, len, - item_number, - start_pos: raw.position(), - iteration_pos: raw.position(), iterated_item_number: 0, } } - - fn len(&self) -> usize { - self.item_number - } } -impl Iterator for ValueArrayIter<'_> { - type Item = Value<'static>; +impl<'a> Iterator for ValueArrayIter<'a> { + type Item = &'a Value<'static>; fn next(&mut self) -> Option { - // Save deserializer position - let iterate_pos = self.raw.position(); - // Goto array items position - self.raw.seek(self.iteration_pos).unwrap(); - let val = if self.iterated_item_number >= self.item_number { - if self.len == Len::Indefinite { - let t = self.raw.cbor_type().unwrap(); - if t == Type::Special { - let special = self.raw.special().unwrap(); - assert_eq!(special, Special::Break); - } + match self { + ValueArrayIter::SE(items) => items.next().map(|v| &v), + DE(d) => { + let val = if d.len == Len::Indefinite { + let t = d.raw.cbor_type().unwrap(); + if t == Type::Special { + let special = d.raw.special().unwrap(); + assert_eq!(special, Special::Break); + } + None + } else { + Some(&Deserialize::deserialize(d.raw).unwrap()) + }; + // Count iterated items + d.iterated_item_number += 1; + val } - None - } else { - Some(Deserialize::deserialize(self.raw).unwrap()) - }; - // Count iterated items - self.iterated_item_number += 1; - // Save current item position for next item - self.iteration_pos = self.raw.position(); - // Restore deserializer position - self.raw.seek(iterate_pos).unwrap(); - val + } } } From 81c6689b979c2451457e8069ce8bce0bc19d11d6 Mon Sep 17 00:00:00 2001 From: SimonIT Date: Wed, 3 Apr 2024 01:13:40 +0200 Subject: [PATCH 07/11] Some borrowing fixes and more alloc feature --- src/de.rs | 13 ++++---- src/lib.rs | 21 ++++++------ src/se.rs | 36 ++++++++++++-------- src/value.rs | 94 ++++++++++++++++++++++++++++------------------------ 4 files changed, 90 insertions(+), 74 deletions(-) diff --git a/src/de.rs b/src/de.rs index db457ac..402e136 100644 --- a/src/de.rs +++ b/src/de.rs @@ -67,7 +67,7 @@ impl<'a> Deserialize<'a> for bool { impl<'a> Deserialize<'a> for f32 { fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { - raw.float().map(|f| f.clone() as f32) + raw.float().map(|f| f as f32) } } @@ -223,8 +223,7 @@ impl<'a> Display for Deserializer<'a> { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { self.data .iter() - .map(|b| f.write_fmt(format_args!("{:02x}", b))) - .collect() + .try_for_each(|b| f.write_fmt(format_args!("{:02x}", b))) } } @@ -1047,7 +1046,7 @@ mod test { let text = raw.text().unwrap(); - assert_eq!(&text, "text"); + assert_eq!(text, "text"); } #[test] fn text_indefinite() { @@ -1069,7 +1068,7 @@ mod test { let text = raw.text().unwrap(); - assert_eq!(&text, ""); + assert_eq!(text, ""); } #[test] @@ -1163,7 +1162,7 @@ mod test { assert_eq!(len, Len::Len(5)); - assert_eq!("iohk", &raw.text().unwrap()); + assert_eq!("iohk", raw.text().unwrap()); assert_eq!(1, raw.unsigned_integer().unwrap()); assert_eq!(-1, raw.negative_integer().unwrap()); @@ -1192,7 +1191,7 @@ mod test { let k = raw.unsigned_integer().unwrap(); let v = raw.text().unwrap(); assert_eq!(0, k); - assert_eq!("text", &v); + assert_eq!("text", v); let k = raw.unsigned_integer().unwrap(); let v = raw.unsigned_integer().unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 51ebe22..3aa6f75 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,11 +59,18 @@ //! ``` #![no_std] +#[cfg(any(feature = "alloc", test))] +extern crate alloc; #[cfg(test)] #[macro_use] extern crate quickcheck; -#[cfg(any(feature = "alloc", test))] -extern crate alloc; + +pub use de::Deserialize; +pub use error::Error; +pub use len::*; +pub use result::Result; +pub use se::Serialize; +pub use types::*; pub mod de; mod error; @@ -74,14 +81,6 @@ pub mod se; mod types; mod value; -pub use de::Deserialize; -pub use error::Error; -pub use len::*; -pub use result::Result; -pub use se::Serialize; -pub use types::*; -pub use value::{ObjectKey, Value}; - const MAX_INLINE_ENCODING: u64 = 23; const CBOR_PAYLOAD_LENGTH_U8: u8 = 24; @@ -101,8 +100,8 @@ pub fn test_encode_decode< B: Deserialize<'c>, V: Sized + PartialEq + Serialize + Deserialize<'a>, >( - data: &'c mut [u8], v: &'c V, + data: &'c mut [u8], ) -> Result<'b, bool> { let mut se = se::Serializer::new(data); v.serialize(&mut se) diff --git a/src/se.rs b/src/se.rs index 2d98c39..83f4b2b 100644 --- a/src/se.rs +++ b/src/se.rs @@ -252,6 +252,7 @@ where ) } +#[cfg(feature = "alloc")] pub fn serialize_cbor_in_cbor<'a, T>( data: T, serializer: &'a mut Serializer<'a>, @@ -261,7 +262,15 @@ where T: Serialize + 'a, { let mut se = Serializer::new(buffer); - data.serialize(&mut se)?; + { + let _ = match data + .serialize(&mut se) + .map_err(|_| Error::CustomError("Failed to serialise")) + { + Ok(_) => {} + Err(e) => return Err(e), + }; + } serializer.write_bytes(&se.finalize()) } @@ -510,16 +519,16 @@ impl<'a> Serializer<'a> { if sz_sum != bytes.len() as u64 { return Err(Error::InvalidIndefiniteString); } - self.write_u8(Type::Bytes.to_byte(0x1f))?; + let mut me = self.write_u8(Type::Bytes.to_byte(0x1f))?; let mut start = 0; for (len, sz) in lens { let end = start + *len as usize; let chunk = &bytes[start..end]; - self.write_bytes_sz(chunk, StringLenSz::Len(*sz))?; + me = me.write_bytes_sz(chunk, StringLenSz::Len(*sz))?; start = end; } - self.write_u8(Type::Special.to_byte(0x1f))?; - Ok(self) + me = me.write_u8(Type::Special.to_byte(0x1f))?; + Ok(me) } } } @@ -556,18 +565,18 @@ impl<'a> Serializer<'a> { if sz_sum != bytes.len() as u64 { return Err(Error::InvalidIndefiniteString); } - self.write_u8(Type::Text.to_byte(0x1f))?; + let mut me = self.write_u8(Type::Text.to_byte(0x1f))?; let mut start = 0; for (len, sz) in lens { let end = start + *len as usize; let chunk = &bytes[start..end]; let chunk_str = core::str::from_utf8(chunk).map_err(|_| Error::InvalidLenPassed(*sz))?; - self.write_text_sz(chunk_str, StringLenSz::Len(*sz))?; + me = me.write_text_sz(chunk_str, StringLenSz::Len(*sz))?; start = end; } - self.write_u8(Type::Special.to_byte(0x1f))?; - Ok(self) + me = me.write_u8(Type::Special.to_byte(0x1f))?; + Ok(me) } } } @@ -794,6 +803,7 @@ serialize_array!( ); #[cfg(test)] +#[cfg(feature = "alloc")] mod test { use super::*; use alloc::vec; @@ -1060,7 +1070,7 @@ mod test { 0xBA, 0xAD, 0xF0, 0x0D, 0xCA, 0xFE, 0xD0, 0x0D, 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBE, 0xEF, ]; - let indef_lens = [ + let indef_lens = &[ (4, Sz::Inline), (4, Sz::One), (4, Sz::Two), @@ -1079,7 +1089,7 @@ mod test { .unwrap() .write_bytes_sz(vec![0xBE, 0xEF], StringLenSz::Len(Sz::Eight)) .unwrap() - .write_bytes_sz(indef_bytes, StringLenSz::Indefinite(*indef_lens)) + .write_bytes_sz(indef_bytes, StringLenSz::Indefinite(indef_lens)) .unwrap(); let bytes = serializer.finalize(); assert_eq!(bytes, expected_bytes); @@ -1105,7 +1115,7 @@ mod test { expected_bytes.copy_from_slice(&slice[..]); } expected_bytes.push(0xFF); - let indef_lens = [ + let indef_lens = &[ (5, Sz::Inline), (5, Sz::One), (9, Sz::Two), @@ -1124,7 +1134,7 @@ mod test { .unwrap() .write_text_sz("ABC", StringLenSz::Len(Sz::Eight)) .unwrap() - .write_text_sz("HelloWorld日本語9ABC", StringLenSz::Indefinite(*indef_lens)) + .write_text_sz("HelloWorld日本語9ABC", StringLenSz::Indefinite(indef_lens)) .unwrap(); let bytes = serializer.finalize(); assert_eq!(bytes, expected_bytes); diff --git a/src/value.rs b/src/value.rs index 6b5ab7b..61855ec 100644 --- a/src/value.rs +++ b/src/value.rs @@ -15,7 +15,6 @@ use core::fmt::Debug; #[cfg(test)] use core::iter::repeat_with; use core::iter::FromIterator; -use core::result::IntoIter; #[cfg(test)] use quickcheck::{Arbitrary, Gen}; @@ -26,16 +25,19 @@ use len::Len; use result::Result; use se::*; use types::{Special, Type}; +#[cfg(feature = "alloc")] use value::ValueArrayIter::DE; /// CBOR Object key, represents the possible supported values for /// a CBOR key in a CBOR Map. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[cfg(feature = "alloc")] pub enum ObjectKey<'a> { Integer(u64), Bytes(&'a [u8]), Text(&'a str), } +#[cfg(feature = "alloc")] impl<'a> ObjectKey<'a> { /// convert the given `ObjectKey` into a CBOR [`Value`](./struct.Value.html) pub fn value(self) -> Value<'a> { @@ -46,6 +48,7 @@ impl<'a> ObjectKey<'a> { } } } +#[cfg(feature = "alloc")] impl<'a> Serialize for ObjectKey<'a> { fn serialize<'se>( &self, @@ -58,6 +61,7 @@ impl<'a> Serialize for ObjectKey<'a> { } } } +#[cfg(feature = "alloc")] impl<'a> Deserialize<'a> for ObjectKey<'a> { fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { match raw.cbor_type()? { @@ -80,6 +84,7 @@ impl<'a> Deserialize<'a> for ObjectKey<'a> { /// so. However it is handy for debugging or reverse a given protocol. /// #[derive(Debug, Clone, PartialEq, PartialOrd)] +#[cfg(feature = "alloc")] pub enum Value<'a> { U64(u64), I64(i64), @@ -87,14 +92,13 @@ pub enum Value<'a> { Text(&'a str), Array(ValueArrayIter<'a>), IArray(ValueArrayIter<'a>), - #[cfg(feature = "alloc")] Object(BTreeMap, Value<'a>>), - #[cfg(feature = "alloc")] IObject(BTreeMap, Value<'a>>), Tag(u64, &'a Value<'a>), Special(Special), } +#[cfg(feature = "alloc")] impl Serialize for Value<'_> { fn serialize<'se>( &'se self, @@ -105,21 +109,20 @@ impl Serialize for Value<'_> { Value::I64(ref v) => serializer.write_negative_integer(*v), Value::Bytes(ref v) => serializer.write_bytes(v), Value::Text(ref v) => serializer.write_text(v), - Value::Array(ref v) => { + Value::Array(ref mut v) => { let mut s = serializer.write_array(Len::Len(v.clone().count() as u64))?; - for element in v.clone().into_iter() { + for element in v { s = s.serialize(&element)?; } Ok(s) } - Value::IArray(v) => { + Value::IArray(ref mut v) => { let mut s = serializer.write_array(Len::Indefinite)?; - for element in v.clone().into_iter() { + for element in v { s = s.serialize(&element)?; } s.write_special(Special::Break) } - #[cfg(feature = "alloc")] Value::Object(ref v) => { serializer.write_map(Len::Len(v.len() as u64))?; for element in v { @@ -127,7 +130,6 @@ impl Serialize for Value<'_> { } Ok(serializer) } - #[cfg(feature = "alloc")] Value::IObject(ref v) => { serializer.write_map(Len::Indefinite)?; for element in v { @@ -140,6 +142,7 @@ impl Serialize for Value<'_> { } } } +#[cfg(feature = "alloc")] impl<'a> Deserialize<'a> for Value<'_> { fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { match raw.cbor_type()? { @@ -181,42 +184,34 @@ impl<'a> Deserialize<'a> for Value<'_> { } } Type::Map => { - #[cfg(feature = "alloc")] - { - let len = raw.map()?; - let mut vec = BTreeMap::new(); - match len { - Len::Indefinite => { - while { - let t = raw.cbor_type()?; - if t == Type::Special { - let special = raw.special()?; - assert_eq!(special, Special::Break); - false - } else { - let k = Deserialize::deserialize(raw)?; - let v = Deserialize::deserialize(raw)?; - vec.insert(k, v); - true - } - } {} - Ok(Value::IObject(vec)) - } - Len::Len(len) => { - for _ in 0..len { + let len = raw.map()?; + let mut vec = BTreeMap::new(); + match len { + Len::Indefinite => { + while { + let t = raw.cbor_type()?; + if t == Type::Special { + let special = raw.special()?; + assert_eq!(special, Special::Break); + false + } else { let k = Deserialize::deserialize(raw)?; let v = Deserialize::deserialize(raw)?; vec.insert(k, v); + true } - Ok(Value::Object(vec)) + } {} + Ok(Value::IObject(vec)) + } + Len::Len(len) => { + for _ in 0..len { + let k = Deserialize::deserialize(raw)?; + let v = Deserialize::deserialize(raw)?; + vec.insert(k, v); } + Ok(Value::Object(vec)) } } - - #[cfg(not(feature = "alloc"))] - { - Err(Error::NoAllocator) - } } Type::Tag => { let tag = raw.tag()?; @@ -227,43 +222,48 @@ impl<'a> Deserialize<'a> for Value<'_> { } } +#[cfg(feature = "alloc")] enum ValueArrayIter<'a> { - SE(&'a IntoIter>), + SE(&'a dyn Iterator>), DE(DeValueArrayIter<'a>), } +#[cfg(feature = "alloc")] impl<'a> ValueArrayIter<'a> { fn new(data: &'a [u8], len: Len) -> Self { DE(DeValueArrayIter::new(data, len)) } } +#[cfg(feature = "alloc")] impl<'a> FromIterator> for ValueArrayIter<'a> { - fn from_iter, IntoIter = &'a IntoIter>>>( - iter: T, - ) -> Self { - ValueArrayIter::SE(iter.into_iter()) + fn from_iter>>(iter: T) -> Self { + ValueArrayIter::SE(&iter.into_iter()) } } +#[cfg(feature = "alloc")] struct DeValueArrayIter<'a> { raw: &'a mut Deserializer<'a>, len: Len, iterated_item_number: usize, } +#[cfg(feature = "alloc")] impl Clone for ValueArrayIter<'_> { fn clone(&self) -> Self { todo!() } } +#[cfg(feature = "alloc")] impl Debug for ValueArrayIter<'_> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_list().entries(self.clone()).finish() } } +#[cfg(feature = "alloc")] impl PartialEq for ValueArrayIter<'_> { fn eq(&self, other: &Self) -> bool { let me = self.clone(); @@ -277,6 +277,7 @@ impl PartialEq for ValueArrayIter<'_> { } } +#[cfg(feature = "alloc")] impl PartialOrd for ValueArrayIter<'_> { fn partial_cmp(&self, other: &Self) -> Option { let me = self.clone(); @@ -293,6 +294,7 @@ impl PartialOrd for ValueArrayIter<'_> { } } +#[cfg(feature = "alloc")] impl<'a> DeValueArrayIter<'a> { fn new(data: &'a [u8], len: Len) -> Self { let mut raw = Deserializer::from(data); @@ -304,6 +306,7 @@ impl<'a> DeValueArrayIter<'a> { } } +#[cfg(feature = "alloc")] impl<'a> Iterator for ValueArrayIter<'a> { type Item = &'a Value<'static>; @@ -330,6 +333,7 @@ impl<'a> Iterator for ValueArrayIter<'a> { } #[cfg(test)] +#[cfg(feature = "alloc")] impl Arbitrary for ObjectKey { fn arbitrary(g: &mut G) -> Self { match u8::arbitrary(g) % 3 { @@ -342,6 +346,7 @@ impl Arbitrary for ObjectKey { } #[cfg(test)] +#[cfg(feature = "alloc")] fn arbitrary_value_finite(g: &mut G) -> Value { match u8::arbitrary(g) % 5 { 0 => Value::U64(Arbitrary::arbitrary(g)), @@ -354,6 +359,7 @@ fn arbitrary_value_finite(g: &mut G) -> Value { } #[cfg(test)] +#[cfg(feature = "alloc")] fn arbitrary_value_indefinite(counter: usize, g: &mut G) -> Value { if counter == 0 { arbitrary_value_finite(g) @@ -416,6 +422,7 @@ fn arbitrary_value_indefinite(counter: usize, g: &mut G) -> Value { } #[cfg(test)] +#[cfg(feature = "alloc")] impl Arbitrary for Value { fn arbitrary(g: &mut G) -> Self { arbitrary_value_indefinite(3, g) @@ -423,6 +430,7 @@ impl Arbitrary for Value { } #[cfg(test)] +#[cfg(feature = "alloc")] mod test { use super::super::test_encode_decode; use super::*; From 0f6560a8de285ca15e887abe95e91539dfb98509 Mon Sep 17 00:00:00 2001 From: SimonIT Date: Wed, 10 Apr 2024 22:48:37 +0200 Subject: [PATCH 08/11] No alloc compiles --- src/de.rs | 166 +++++++++++++++++-------------- src/value.rs | 273 ++++++++++++++++----------------------------------- 2 files changed, 176 insertions(+), 263 deletions(-) diff --git a/src/de.rs b/src/de.rs index 402e136..a81f688 100644 --- a/src/de.rs +++ b/src/de.rs @@ -102,7 +102,7 @@ impl<'a, T: Deserialize<'a>> Deserialize<'a> for Vec { } } #[cfg(feature = "alloc")] -impl<'a, K: Deserialize + Ord, V: Deserialize<'a>> Deserialize<'a> for BTreeMap { +impl<'a, K: Deserialize<'a> + Ord, V: Deserialize<'a>> Deserialize<'a> for BTreeMap { fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { let mut vec = BTreeMap::new(); raw.map_with(|raw| { @@ -193,10 +193,10 @@ pub struct Deserializer<'a> { } #[cfg(feature = "alloc")] -impl From> for Deserializer { +impl From> for Deserializer<'_> { fn from(r: Vec) -> Self { Deserializer { - data: r.as_slice(), + data: r.as_ref(), pos: 0, allocate: Some(move |len| Vec::with_capacity(len).as_mut_slice()), } @@ -989,7 +989,7 @@ mod test { #[test] fn negative_integer() { - let vec = vec![0x38, 0x29]; + let vec = [0x38, 0x29].as_ref(); let mut raw = Deserializer::from(vec); let integer = raw.negative_integer().unwrap(); @@ -999,23 +999,25 @@ mod test { #[test] fn bytes() { - let vec = vec![ + let vec = [ 0x52, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x72, 0x61, 0x6E, 0x64, 0x6F, 0x6D, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, - ]; - let mut raw = Deserializer::from(vec.clone()); + ] + .as_ref(); + let mut raw = Deserializer::from(vec); let bytes = raw.bytes().unwrap(); assert_eq!(&vec[1..], &*bytes); } #[test] fn bytes_indefinite() { - let chunks = vec![ - vec![ + let chunks = [ + [ 0x52, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x72, 0x61, 0x6E, 0x64, 0x6F, 0x6D, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, - ], - vec![0x44, 0x01, 0x02, 0x03, 0x04], + ] + .as_ref(), + [0x44, 0x01, 0x02, 0x03, 0x04].as_ref(), ]; let mut expected = Vec::new(); for chunk in chunks.iter() { @@ -1023,16 +1025,16 @@ mod test { } let mut vec = vec![0x5f]; for mut chunk in chunks { - vec.append(&mut chunk); + vec.extend_from_slice(&mut chunk); } vec.push(0xff); - let mut raw = Deserializer::from(vec.clone()); + let mut raw = Deserializer::from(vec.as_slice()); let found = raw.bytes().unwrap(); assert_eq!(found, expected); } #[test] fn bytes_empty() { - let vec = vec![0x40]; + let vec = [0x40].as_ref(); let mut raw = Deserializer::from(vec); let bytes = raw.bytes().unwrap(); @@ -1041,7 +1043,7 @@ mod test { #[test] fn text() { - let vec = vec![0x64, 0x74, 0x65, 0x78, 0x74]; + let vec = [0x64, 0x74, 0x65, 0x78, 0x74].as_ref(); let mut raw = Deserializer::from(vec); let text = raw.text().unwrap(); @@ -1050,20 +1052,23 @@ mod test { } #[test] fn text_indefinite() { - let chunks = vec![vec![0x64, 0x49, 0x45, 0x54, 0x46], vec![0x61, 0x61]]; + let chunks = [ + [0x64, 0x49, 0x45, 0x54, 0x46].as_ref(), + [0x61, 0x61].as_ref(), + ]; let expected = "IETFa"; let mut vec = vec![0x7f]; for mut chunk in chunks { - vec.append(&mut chunk); + vec.extend_from_slice(&mut chunk); } vec.push(0xff); - let mut raw = Deserializer::from(vec.clone()); + let mut raw = Deserializer::from(vec.as_slice()); let found = raw.text().unwrap(); assert_eq!(found, expected); } #[test] fn text_empty() { - let vec = vec![0x60]; + let vec = [0x60].as_ref(); let mut raw = Deserializer::from(vec); let text = raw.text().unwrap(); @@ -1073,7 +1078,7 @@ mod test { #[test] fn float64() { - let vec = vec![0xfb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a]; + let vec = [0xfb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a].as_ref(); let mut raw = Deserializer::from(vec); let float = raw.float().unwrap(); @@ -1083,7 +1088,7 @@ mod test { #[test] fn float32() { - let vec = vec![0xfa, 0x47, 0xc3, 0x50, 0x00]; + let vec = [0xfa, 0x47, 0xc3, 0x50, 0x00].as_ref(); let mut raw = Deserializer::from(vec); let float = raw.float().unwrap(); @@ -1093,7 +1098,7 @@ mod test { #[test] fn array() { - let vec = vec![0x86, 0, 1, 2, 3, 4, 5]; + let vec = [0x86, 0, 1, 2, 3, 4, 5].as_ref(); let mut raw = Deserializer::from(vec); let len = raw.array().unwrap(); @@ -1110,7 +1115,7 @@ mod test { } #[test] fn array_empty() { - let vec = vec![0x80]; + let vec = [0x80].as_ref(); let mut raw = Deserializer::from(vec); let len = raw.array().unwrap(); @@ -1120,7 +1125,7 @@ mod test { } #[test] fn array_indefinite() { - let vec = vec![0x9F, 0x01, 0x02, 0xFF]; + let vec = [0x9F, 0x01, 0x02, 0xFF].as_ref(); let mut raw = Deserializer::from(vec); let len = raw.array().unwrap(); @@ -1129,22 +1134,24 @@ mod test { // assert_eq!(&*raw, &[0x01, 0x02, 0xFF][..]); let i = raw.unsigned_integer().unwrap(); - assert!(i == 1); + assert_eq!(i, 1); let i = raw.unsigned_integer().unwrap(); - assert!(i == 2); + assert_eq!(i, 2); assert_eq!(Special::Break, raw.special().unwrap()); } #[test] + #[cfg(feature = "alloc")] fn vec_bool_definite() { - let vec = vec![0x83, 0xf4, 0xf5, 0xf4]; + let vec = [0x83, 0xf4, 0xf5, 0xf4].as_ref(); let mut raw = Deserializer::from(vec); let bools = Vec::::deserialize(&mut raw).unwrap(); assert_eq!(bools, &[false, true, false]); } #[test] + #[cfg(feature = "alloc")] fn vec_bool_indefinite() { - let vec = vec![0x9f, 0xf4, 0xf5, 0xf4, 0xff]; + let vec = [0x9f, 0xf4, 0xf5, 0xf4, 0xff].as_ref(); let mut raw = Deserializer::from(vec); let bools = Vec::::deserialize(&mut raw).unwrap(); assert_eq!(bools, &[false, true, false]); @@ -1152,10 +1159,11 @@ mod test { #[test] fn complex_array() { - let vec = vec![ + let vec = [ 0x85, 0x64, 0x69, 0x6F, 0x68, 0x6B, 0x01, 0x20, 0x84, 0, 1, 2, 3, 0x10, /* garbage... */ 0, 1, 2, 3, 4, 5, 6, - ]; + ] + .as_ref(); let mut raw = Deserializer::from(vec); let len = raw.array().unwrap(); @@ -1181,7 +1189,7 @@ mod test { #[test] fn map() { - let vec = vec![0xA2, 0x00, 0x64, 0x74, 0x65, 0x78, 0x74, 0x01, 0x18, 0x2A]; + let vec = [0xA2, 0x00, 0x64, 0x74, 0x65, 0x78, 0x74, 0x01, 0x18, 0x2A].as_ref(); let mut raw = Deserializer::from(vec); let len = raw.map().unwrap(); @@ -1201,7 +1209,7 @@ mod test { #[test] fn map_empty() { - let vec = vec![0xA0]; + let vec = [0xA0].as_ref(); let mut raw = Deserializer::from(vec); let len = raw.map().unwrap(); @@ -1210,8 +1218,9 @@ mod test { } #[test] + #[cfg(feature = "alloc")] fn btreemap_bool_definite() { - let vec = vec![0xa2, 0xf4, 0xf5, 0xf5, 0xf4]; + let vec = [0xa2, 0xf4, 0xf5, 0xf5, 0xf4].as_ref(); let mut raw = Deserializer::from(vec); let boolmap = BTreeMap::::deserialize(&mut raw).unwrap(); assert_eq!(boolmap.len(), 2); @@ -1219,8 +1228,9 @@ mod test { assert_eq!(boolmap[&true], false); } #[test] + #[cfg(feature = "alloc")] fn btreemap_bool_indefinite() { - let vec = vec![0xbf, 0xf4, 0xf5, 0xf5, 0xf4, 0xff]; + let vec = [0xbf, 0xf4, 0xf5, 0xf5, 0xf4, 0xff].as_ref(); let mut raw = Deserializer::from(vec); let boolmap = BTreeMap::::deserialize(&mut raw).unwrap(); assert_eq!(boolmap.len(), 2); @@ -1230,10 +1240,11 @@ mod test { #[test] fn tag() { - let vec = vec![ + let vec = [ 0xD8, 0x18, 0x52, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x72, 0x61, 0x6E, 0x64, 0x6F, 0x6D, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, - ]; + ] + .as_ref(); let mut raw = Deserializer::from(vec); let tag = raw.tag().unwrap(); @@ -1245,17 +1256,18 @@ mod test { #[test] fn tag2() { - let vec = vec![ + let vec = [ 0x82, 0xd8, 0x18, 0x53, 0x52, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x1a, 0x71, 0xad, 0x58, 0x36, - ]; + ] + .as_ref(); let mut raw = Deserializer::from(vec); let len = raw.array().unwrap(); assert_eq!(len, Len::Len(2)); let tag = raw.tag().unwrap(); - assert!(tag == 24); + assert_eq!(tag, 24); let _ = raw.bytes().unwrap(); let crc = raw.unsigned_integer().unwrap(); @@ -1264,10 +1276,11 @@ mod test { #[test] fn uint_sz() { - let vec = vec![ + let vec = [ 0x09, 0x18, 0x09, 0x19, 0x00, 0x09, 0x1a, 0x00, 0x00, 0x00, 0x09, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - ]; + ] + .as_ref(); let mut raw = Deserializer::from(vec); assert_eq!(raw.unsigned_integer_sz().unwrap(), (9, Sz::Inline)); assert_eq!(raw.unsigned_integer_sz().unwrap(), (9, Sz::One)); @@ -1278,10 +1291,11 @@ mod test { #[test] fn nint_sz() { - let vec = vec![ + let vec = [ 0x28, 0x38, 0x08, 0x39, 0x00, 0x08, 0x3a, 0x00, 0x00, 0x00, 0x08, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - ]; + ] + .as_ref(); let mut raw = Deserializer::from(vec); assert_eq!(raw.negative_integer_sz().unwrap(), (-9, Sz::Inline)); assert_eq!(raw.negative_integer_sz().unwrap(), (-9, Sz::One)); @@ -1308,40 +1322,45 @@ mod test { vec.extend_from_slice(&slice[..]); } vec.push(0xFF); - let mut raw = Deserializer::from(vec); - let indef_bytes = vec![ + let mut raw = Deserializer::from(vec.as_slice()); + let indef_bytes = [ 0xBA, 0xAD, 0xF0, 0x0D, 0xCA, 0xFE, 0xD0, 0x0D, 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBE, 0xEF, - ]; - let indef_lens = &[ + ] + .as_ref(); + let indef_lens = [ (4, Sz::Inline), (4, Sz::One), (4, Sz::Two), (2, Sz::Four), (2, Sz::Eight), - ]; + ] + .as_ref(); assert_eq!( - raw.bytes_sz_vec().unwrap(), - (vec![0xBA, 0xAD, 0xF0, 0x0D], StringLenSz::Len(Sz::Inline)) + raw.bytes_sz(None).unwrap(), + ( + [0xBA, 0xAD, 0xF0, 0x0D].as_ref(), + StringLenSz::Len(Sz::Inline) + ) ); assert_eq!( - raw.bytes_sz_vec().unwrap(), - (vec![0xCA, 0xFE, 0xD0, 0x0D], StringLenSz::Len(Sz::One)) + raw.bytes_sz(None).unwrap(), + ([0xCA, 0xFE, 0xD0, 0x0D].as_ref(), StringLenSz::Len(Sz::One)) ); assert_eq!( - raw.bytes_sz_vec().unwrap(), - (vec![0xDE, 0xAD, 0xBE, 0xEF], StringLenSz::Len(Sz::Two)) + raw.bytes_sz(None).unwrap(), + ([0xDE, 0xAD, 0xBE, 0xEF].as_ref(), StringLenSz::Len(Sz::Two)) ); assert_eq!( - raw.bytes_sz_vec().unwrap(), - (vec![0xCA, 0xFE], StringLenSz::Len(Sz::Four)) + raw.bytes_sz(None).unwrap(), + ([0xCA, 0xFE].as_ref(), StringLenSz::Len(Sz::Four)) ); assert_eq!( - raw.bytes_sz_vec().unwrap(), - (vec![0xBE, 0xEF], StringLenSz::Len(Sz::Eight)) + raw.bytes_sz(None).unwrap(), + ([0xBE, 0xEF].as_ref(), StringLenSz::Len(Sz::Eight)) ); assert_eq!( - raw.bytes_sz_vec().unwrap(), + raw.bytes_sz(None).unwrap(), (indef_bytes, StringLenSz::Indefinite(indef_lens)) ); } @@ -1366,7 +1385,7 @@ mod test { vec.extend_from_slice(&slice[..]); } vec.push(0xFF); - let mut raw = Deserializer::from(vec); + let mut raw = Deserializer::from(vec.as_slice()); let indef_lens = &[ (5, Sz::Inline), (5, Sz::One), @@ -1375,27 +1394,27 @@ mod test { (3, Sz::Eight), ]; assert_eq!( - raw.text_sz_vec().unwrap(), + raw.text_sz(None).unwrap(), ("Hello".into(), StringLenSz::Len(Sz::Inline)) ); assert_eq!( - raw.text_sz_vec().unwrap(), + raw.text_sz(None).unwrap(), ("World".into(), StringLenSz::Len(Sz::One)) ); assert_eq!( - raw.text_sz_vec().unwrap(), + raw.text_sz(None).unwrap(), ("日本語".into(), StringLenSz::Len(Sz::Two)) ); assert_eq!( - raw.text_sz_vec().unwrap(), + raw.text_sz(None).unwrap(), ("9".into(), StringLenSz::Len(Sz::Four)) ); assert_eq!( - raw.text_sz_vec().unwrap(), + raw.text_sz(None).unwrap(), ("ABC".into(), StringLenSz::Len(Sz::Eight)) ); assert_eq!( - raw.text_sz_vec().unwrap(), + raw.text_sz(None).unwrap(), ( "HelloWorld日本語9ABC".into(), StringLenSz::Indefinite(indef_lens) @@ -1405,10 +1424,11 @@ mod test { #[test] fn array_sz() { - let vec = vec![ + let vec = [ 0x80, 0x98, 0x01, 0x99, 0x00, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x03, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x9f, - ]; + ] + .as_ref(); let mut raw = Deserializer::from(vec); assert_eq!(raw.array_sz().unwrap(), LenSz::Len(0, Sz::Inline)); assert_eq!(raw.array_sz().unwrap(), LenSz::Len(1, Sz::One)); @@ -1420,10 +1440,11 @@ mod test { #[test] fn map_sz() { - let vec = vec![ + let vec = [ 0xa0, 0xb8, 0x01, 0xb9, 0x00, 0x02, 0xba, 0x00, 0x00, 0x00, 0x03, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xbf, - ]; + ] + .as_ref(); let mut raw = Deserializer::from(vec); assert_eq!(raw.map_sz().unwrap(), LenSz::Len(0, Sz::Inline)); assert_eq!(raw.map_sz().unwrap(), LenSz::Len(1, Sz::One)); @@ -1435,10 +1456,11 @@ mod test { #[test] fn tag_sz() { - let vec = vec![ + let vec = [ 0xc9, 0xd8, 0x01, 0xd9, 0x00, 0x02, 0xda, 0x00, 0x00, 0x00, 0x04, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - ]; + ] + .as_ref(); let mut raw = Deserializer::from(vec); assert_eq!(raw.tag_sz().unwrap(), (9, Sz::Inline)); assert_eq!(raw.tag_sz().unwrap(), (1, Sz::One)); diff --git a/src/value.rs b/src/value.rs index 61855ec..acbba95 100644 --- a/src/value.rs +++ b/src/value.rs @@ -9,12 +9,16 @@ //! //! This is why all the objects here are marked as deprecated +#[cfg(feature = "alloc")] +use alloc::boxed::Box; #[cfg(feature = "alloc")] use alloc::collections::BTreeMap; -use core::fmt::Debug; +#[cfg(feature = "alloc")] +use alloc::string::{String, ToString}; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; #[cfg(test)] use core::iter::repeat_with; -use core::iter::FromIterator; #[cfg(test)] use quickcheck::{Arbitrary, Gen}; @@ -25,22 +29,20 @@ use len::Len; use result::Result; use se::*; use types::{Special, Type}; -#[cfg(feature = "alloc")] -use value::ValueArrayIter::DE; /// CBOR Object key, represents the possible supported values for /// a CBOR key in a CBOR Map. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[cfg(feature = "alloc")] -pub enum ObjectKey<'a> { +pub enum ObjectKey { Integer(u64), - Bytes(&'a [u8]), - Text(&'a str), + Bytes(Vec), + Text(String), } #[cfg(feature = "alloc")] -impl<'a> ObjectKey<'a> { +impl ObjectKey { /// convert the given `ObjectKey` into a CBOR [`Value`](./struct.Value.html) - pub fn value(self) -> Value<'a> { + pub fn value(self) -> Value { match self { ObjectKey::Integer(v) => Value::U64(v), ObjectKey::Bytes(v) => Value::Bytes(v), @@ -49,7 +51,7 @@ impl<'a> ObjectKey<'a> { } } #[cfg(feature = "alloc")] -impl<'a> Serialize for ObjectKey<'a> { +impl<'a> Serialize for ObjectKey { fn serialize<'se>( &self, serializer: &'se mut Serializer<'se>, @@ -62,12 +64,12 @@ impl<'a> Serialize for ObjectKey<'a> { } } #[cfg(feature = "alloc")] -impl<'a> Deserialize<'a> for ObjectKey<'a> { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { +impl<'a> Deserialize<'a> for ObjectKey { + fn deserialize(raw: &'a mut Deserializer) -> Result<'a, Self> { match raw.cbor_type()? { Type::UnsignedInteger => Ok(ObjectKey::Integer(raw.unsigned_integer()?)), - Type::Bytes => Ok(ObjectKey::Bytes(raw.bytes()?)), - Type::Text => Ok(ObjectKey::Text(raw.text()?)), + Type::Bytes => Ok(ObjectKey::Bytes(raw.bytes()?.to_vec())), + Type::Text => Ok(ObjectKey::Text(raw.text()?.to_string())), t => Err(Error::CustomError( format_args!("Type `{:?}' is not a support type for CBOR Map's key", t) .as_str() @@ -85,38 +87,35 @@ impl<'a> Deserialize<'a> for ObjectKey<'a> { /// #[derive(Debug, Clone, PartialEq, PartialOrd)] #[cfg(feature = "alloc")] -pub enum Value<'a> { +pub enum Value { U64(u64), I64(i64), - Bytes(&'a [u8]), - Text(&'a str), - Array(ValueArrayIter<'a>), - IArray(ValueArrayIter<'a>), - Object(BTreeMap, Value<'a>>), - IObject(BTreeMap, Value<'a>>), - Tag(u64, &'a Value<'a>), + Bytes(Vec), + Text(String), + Array(Vec), + IArray(Vec), + Object(BTreeMap), + IObject(BTreeMap), + Tag(u64, Box), Special(Special), } #[cfg(feature = "alloc")] -impl Serialize for Value<'_> { - fn serialize<'se>( - &'se self, - serializer: &'se mut Serializer<'se>, - ) -> Result<'se, &'se mut Serializer<'se>> { +impl Serialize for Value { + fn serialize<'se>(&self, serializer: &'se mut Serializer) -> Result<&'se mut Serializer> { match self { Value::U64(ref v) => serializer.write_unsigned_integer(*v), Value::I64(ref v) => serializer.write_negative_integer(*v), Value::Bytes(ref v) => serializer.write_bytes(v), Value::Text(ref v) => serializer.write_text(v), - Value::Array(ref mut v) => { - let mut s = serializer.write_array(Len::Len(v.clone().count() as u64))?; + Value::Array(ref v) => { + let mut s = serializer.write_array(Len::Len(v.len() as u64))?; for element in v { s = s.serialize(&element)?; } Ok(s) } - Value::IArray(ref mut v) => { + Value::IArray(ref v) => { let mut s = serializer.write_array(Len::Indefinite)?; for element in v { s = s.serialize(&element)?; @@ -124,37 +123,37 @@ impl Serialize for Value<'_> { s.write_special(Special::Break) } Value::Object(ref v) => { - serializer.write_map(Len::Len(v.len() as u64))?; + let mut s = serializer.write_map(Len::Len(v.len() as u64))?; for element in v { - serializer.serialize(element.0)?.serialize(element.1)?; + s = s.serialize(element.0)?.serialize(element.1)?; } - Ok(serializer) + Ok(s) } Value::IObject(ref v) => { - serializer.write_map(Len::Indefinite)?; + let mut s = serializer.write_map(Len::Indefinite)?; for element in v { - serializer.serialize(element.0)?.serialize(element.1)?; + s = s.serialize(element.0)?.serialize(element.1)?; } - serializer.write_special(Special::Break) + s.write_special(Special::Break) } - Value::Tag(ref tag, ref v) => serializer.write_tag(*tag)?.serialize(v), + Value::Tag(ref tag, ref v) => serializer.write_tag(*tag)?.serialize(v.as_ref()), Value::Special(ref v) => serializer.write_special(*v), } } } #[cfg(feature = "alloc")] -impl<'a> Deserialize<'a> for Value<'_> { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { +impl<'a> Deserialize<'a> for Value { + fn deserialize(raw: &'a mut Deserializer) -> Result<'a, Self> { match raw.cbor_type()? { Type::UnsignedInteger => Ok(Value::U64(raw.unsigned_integer()?)), Type::NegativeInteger => Ok(Value::I64(raw.negative_integer()?)), - Type::Bytes => Ok(Value::Bytes(raw.bytes()?)), - Type::Text => Ok(Value::Text(raw.text()?)), + Type::Bytes => Ok(Value::Bytes(raw.bytes()?.to_vec())), + Type::Text => Ok(Value::Text(raw.text()?.to_string())), Type::Array => { let len = raw.array()?; + let mut vec = Vec::new(); match len { Len::Indefinite => { - let start = raw.position(); while { let t = raw.cbor_type()?; if t == Type::Special { @@ -162,24 +161,17 @@ impl<'a> Deserialize<'a> for Value<'_> { assert_eq!(special, Special::Break); false } else { - Value::deserialize(raw)?; + vec.push(Deserialize::deserialize(raw)?); true } } {} - Ok(Value::IArray(ValueArrayIter::new( - &raw.inner()[start..raw.position()], - len, - ))) + Ok(Value::IArray(vec)) } - Len::Len(item_count) => { - let start = raw.position(); - (0..item_count).for_each(|_| { - Value::deserialize(raw); - }); - Ok(Value::Array(ValueArrayIter::new( - &raw.inner()[start..raw.position()], - len, - ))) + Len::Len(len) => { + for _ in 0..len { + vec.push(Deserialize::deserialize(raw)?); + } + Ok(Value::Array(vec)) } } } @@ -215,7 +207,7 @@ impl<'a> Deserialize<'a> for Value<'_> { } Type::Tag => { let tag = raw.tag()?; - Ok(Value::Tag(tag, &Deserialize::deserialize(raw)?)) + Ok(Value::Tag(tag, Box::new(Deserialize::deserialize(raw)?))) } Type::Special => Ok(Value::Special(raw.special()?)), } @@ -223,117 +215,7 @@ impl<'a> Deserialize<'a> for Value<'_> { } #[cfg(feature = "alloc")] -enum ValueArrayIter<'a> { - SE(&'a dyn Iterator>), - DE(DeValueArrayIter<'a>), -} - -#[cfg(feature = "alloc")] -impl<'a> ValueArrayIter<'a> { - fn new(data: &'a [u8], len: Len) -> Self { - DE(DeValueArrayIter::new(data, len)) - } -} - -#[cfg(feature = "alloc")] -impl<'a> FromIterator> for ValueArrayIter<'a> { - fn from_iter>>(iter: T) -> Self { - ValueArrayIter::SE(&iter.into_iter()) - } -} - -#[cfg(feature = "alloc")] -struct DeValueArrayIter<'a> { - raw: &'a mut Deserializer<'a>, - len: Len, - iterated_item_number: usize, -} - -#[cfg(feature = "alloc")] -impl Clone for ValueArrayIter<'_> { - fn clone(&self) -> Self { - todo!() - } -} - -#[cfg(feature = "alloc")] -impl Debug for ValueArrayIter<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_list().entries(self.clone()).finish() - } -} - -#[cfg(feature = "alloc")] -impl PartialEq for ValueArrayIter<'_> { - fn eq(&self, other: &Self) -> bool { - let me = self.clone(); - let mut other = other.clone(); - for i in me.into_iter() { - if i != other.next().unwrap() { - return false; - } - } - true - } -} - -#[cfg(feature = "alloc")] -impl PartialOrd for ValueArrayIter<'_> { - fn partial_cmp(&self, other: &Self) -> Option { - let me = self.clone(); - let mut other = other.clone(); - me.into_iter() - .map(|i| i.partial_cmp(&other.next().unwrap())) - .fold(Some(core::cmp::Ordering::Equal), |acc, x| { - if acc == Some(core::cmp::Ordering::Equal) { - x - } else { - acc - } - }) - } -} - -#[cfg(feature = "alloc")] -impl<'a> DeValueArrayIter<'a> { - fn new(data: &'a [u8], len: Len) -> Self { - let mut raw = Deserializer::from(data); - DeValueArrayIter { - raw: &mut raw, - len, - iterated_item_number: 0, - } - } -} - -#[cfg(feature = "alloc")] -impl<'a> Iterator for ValueArrayIter<'a> { - type Item = &'a Value<'static>; - - fn next(&mut self) -> Option { - match self { - ValueArrayIter::SE(items) => items.next().map(|v| &v), - DE(d) => { - let val = if d.len == Len::Indefinite { - let t = d.raw.cbor_type().unwrap(); - if t == Type::Special { - let special = d.raw.special().unwrap(); - assert_eq!(special, Special::Break); - } - None - } else { - Some(&Deserialize::deserialize(d.raw).unwrap()) - }; - // Count iterated items - d.iterated_item_number += 1; - val - } - } - } -} - #[cfg(test)] -#[cfg(feature = "alloc")] impl Arbitrary for ObjectKey { fn arbitrary(g: &mut G) -> Self { match u8::arbitrary(g) % 3 { @@ -345,8 +227,8 @@ impl Arbitrary for ObjectKey { } } -#[cfg(test)] #[cfg(feature = "alloc")] +#[cfg(test)] fn arbitrary_value_finite(g: &mut G) -> Value { match u8::arbitrary(g) % 5 { 0 => Value::U64(Arbitrary::arbitrary(g)), @@ -358,8 +240,8 @@ fn arbitrary_value_finite(g: &mut G) -> Value { } } -#[cfg(test)] #[cfg(feature = "alloc")] +#[cfg(test)] fn arbitrary_value_indefinite(counter: usize, g: &mut G) -> Value { if counter == 0 { arbitrary_value_finite(g) @@ -421,17 +303,20 @@ fn arbitrary_value_indefinite(counter: usize, g: &mut G) -> Value { } } -#[cfg(test)] #[cfg(feature = "alloc")] +#[cfg(test)] impl Arbitrary for Value { fn arbitrary(g: &mut G) -> Self { arbitrary_value_indefinite(3, g) } } -#[cfg(test)] #[cfg(feature = "alloc")] +#[cfg(test)] mod test { + use alloc::borrow::ToOwned; + use alloc::vec; + use super::super::test_encode_decode; use super::*; @@ -461,42 +346,48 @@ mod test { #[test] fn bytes() { - assert!(test_encode_decode(&Value::Bytes(&[])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(&[0; 23])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(&[0; 24])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(&[0; 256])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(&[0; 10293])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(&[0; 99999000])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(vec![])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(vec![0; 23])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(vec![0; 24])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(vec![0; 256])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(vec![0; 10293])).unwrap()); + assert!(test_encode_decode(&Value::Bytes(vec![0; 99999000])).unwrap()); } #[test] fn text() { - assert!(test_encode_decode(&Value::Text("")).unwrap()); - assert!(test_encode_decode(&Value::Text("hellow world")).unwrap()); - assert!(test_encode_decode(&Value::Text("some sentence, some sentence... some sentence...some sentence, some sentence... some sentence...")).unwrap()); + assert!(test_encode_decode(&Value::Text("".to_owned())).unwrap()); + assert!(test_encode_decode(&Value::Text("hellow world".to_owned())).unwrap()); + assert!(test_encode_decode(&Value::Text("some sentence, some sentence... some sentence...some sentence, some sentence... some sentence...".to_owned())).unwrap()); } #[test] fn array() { - assert!(test_encode_decode(&Value::Array(&[])).unwrap()); - assert!( - test_encode_decode(&Value::Array(&[Value::U64(0), Value::Text("some text")])).unwrap() - ); + assert!(test_encode_decode(&Value::Array(vec![])).unwrap()); + assert!(test_encode_decode(&Value::Array(vec![ + Value::U64(0), + Value::Text("some text".to_owned()) + ])) + .unwrap()); } #[test] fn iarray() { - assert!(test_encode_decode(&Value::IArray(&[])).unwrap()); - assert!( - test_encode_decode(&Value::IArray(&[Value::U64(0), Value::Text("some text")])).unwrap() - ); + assert!(test_encode_decode(&Value::IArray(vec![])).unwrap()); + assert!(test_encode_decode(&Value::IArray(vec![ + Value::U64(0), + Value::Text("some text".to_owned()) + ])) + .unwrap()); } #[test] fn tag() { - assert!(test_encode_decode(&Value::Tag(23, &Value::U64(0))).unwrap()); - assert!(test_encode_decode(&Value::Tag(24, &Value::Bytes(&[0; 32]))).unwrap()); - assert!(test_encode_decode(&Value::Tag(0x1ff, &Value::Bytes(&[0; 624]))).unwrap()); + assert!(test_encode_decode(&Value::Tag(23, Box::new(Value::U64(0)))).unwrap()); + assert!(test_encode_decode(&Value::Tag(24, Box::new(Value::Bytes(vec![0; 32])))).unwrap()); + assert!( + test_encode_decode(&Value::Tag(0x1ff, Box::new(Value::Bytes(vec![0; 624])))).unwrap() + ); } quickcheck! { From fdfeb034691279a859ce7a0641f8e92fe3d2c44a Mon Sep 17 00:00:00 2001 From: SimonIT Date: Mon, 22 Apr 2024 23:27:16 +0200 Subject: [PATCH 09/11] Remove lifetime from Result and Erro --- src/de.rs | 129 ++++++++++++++------------------- src/error.rs | 10 +-- src/lib.rs | 7 +- src/result.rs | 2 +- src/se.rs | 193 +++++++++++++++++++++----------------------------- src/types.rs | 12 ++-- src/value.rs | 11 +-- 7 files changed, 155 insertions(+), 209 deletions(-) diff --git a/src/de.rs b/src/de.rs index a81f688..d5792aa 100644 --- a/src/de.rs +++ b/src/de.rs @@ -17,11 +17,11 @@ use types::{Special, Type}; pub trait Deserialize<'a>: Sized { /// method to implement to deserialise an object from the given /// `Deserializer`. - fn deserialize(reader: &mut Deserializer<'a>) -> Result<'a, Self>; + fn deserialize(reader: &mut Deserializer<'a>) -> Result; } impl<'a> Deserialize<'a> for u8 { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { let n = raw.unsigned_integer()?; if n > u8::MAX as u64 { Err(Error::ExpectedU8) @@ -32,7 +32,7 @@ impl<'a> Deserialize<'a> for u8 { } impl<'a> Deserialize<'a> for u16 { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { let n = raw.unsigned_integer()?; if n > u16::MAX as u64 { Err(Error::ExpectedU16) @@ -43,7 +43,7 @@ impl<'a> Deserialize<'a> for u16 { } impl<'a> Deserialize<'a> for u32 { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { let n = raw.unsigned_integer()?; if n > u32::MAX as u64 { Err(Error::ExpectedU32) @@ -54,45 +54,45 @@ impl<'a> Deserialize<'a> for u32 { } impl<'a> Deserialize<'a> for u64 { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { raw.unsigned_integer() } } impl<'a> Deserialize<'a> for bool { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { raw.bool() } } impl<'a> Deserialize<'a> for f32 { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { raw.float().map(|f| f as f32) } } impl<'a> Deserialize<'a> for f64 { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { raw.float() } } impl<'a> Deserialize<'a> for &'a str { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { raw.text() } } #[cfg(feature = "alloc")] impl<'a> Deserialize<'a> for String { - fn deserialize(raw: &mut Deserializer) -> Result<'a, Self> { - raw.text().map(|s| s.to_string()) + fn deserialize(raw: &mut Deserializer<'a>) -> Result { + raw.text().map(move |s| s.to_string()) } } #[cfg(feature = "alloc")] impl<'a, T: Deserialize<'a>> Deserialize<'a> for Vec { - fn deserialize(raw: &mut Deserializer) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { let mut vec = Vec::new(); raw.array_with(|raw| { vec.push(Deserialize::deserialize(raw)?); @@ -103,7 +103,7 @@ impl<'a, T: Deserialize<'a>> Deserialize<'a> for Vec { } #[cfg(feature = "alloc")] impl<'a, K: Deserialize<'a> + Ord, V: Deserialize<'a>> Deserialize<'a> for BTreeMap { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { let mut vec = BTreeMap::new(); raw.map_with(|raw| { let k = Deserialize::deserialize(raw)?; @@ -116,7 +116,7 @@ impl<'a, K: Deserialize<'a> + Ord, V: Deserialize<'a>> Deserialize<'a> for BTree } impl<'a, T: Deserialize<'a>> Deserialize<'a> for Option { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { match raw.array()? { Len::Len(0) => Ok(None), Len::Len(1) => Ok(Some(raw.deserialize()?)), @@ -192,17 +192,6 @@ pub struct Deserializer<'a> { allocate: Option &'a mut [u8]>, } -#[cfg(feature = "alloc")] -impl From> for Deserializer<'_> { - fn from(r: Vec) -> Self { - Deserializer { - data: r.as_ref(), - pos: 0, - allocate: Some(move |len| Vec::with_capacity(len).as_mut_slice()), - } - } -} - impl<'a> From<&'a [u8]> for Deserializer<'a> { fn from(r: &'a [u8]) -> Self { Deserializer { @@ -233,25 +222,25 @@ impl<'a> Deserializer<'a> { } #[inline] - fn get(&mut self, index: usize) -> Result<'a, &u8> { + fn get(&mut self, index: usize) -> Result<&u8> { match self.data.get(self.pos + index) { None => Err(Error::NotEnough(self.data.len(), index)), Some(b) => Ok(b), } } #[inline] - fn u8(&mut self, index: usize) -> Result<'a, u64> { + fn u8(&mut self, index: usize) -> Result { let b = self.get(index)?; Ok(*b as u64) } #[inline] - fn u16(&mut self, index: usize) -> Result<'a, u64> { + fn u16(&mut self, index: usize) -> Result { let b1 = self.u8(index)?; let b2 = self.u8(index + 1)?; Ok(b1 << 8 | b2) } #[inline] - fn u32(&mut self, index: usize) -> Result<'a, u64> { + fn u32(&mut self, index: usize) -> Result { let b1 = self.u8(index)?; let b2 = self.u8(index + 1)?; let b3 = self.u8(index + 2)?; @@ -259,7 +248,7 @@ impl<'a> Deserializer<'a> { Ok(b1 << 24 | b2 << 16 | b3 << 8 | b4) } #[inline] - fn u64(&mut self, index: usize) -> Result<'a, u64> { + fn u64(&mut self, index: usize) -> Result { let b1 = self.u8(index)?; let b2 = self.u8(index + 1)?; let b3 = self.u8(index + 2)?; @@ -287,11 +276,11 @@ impl<'a> Deserializer<'a> { /// assert!(cbor_type == Type::UnsignedInteger); /// ``` #[inline] - pub fn cbor_type(&mut self) -> Result<'a, Type> { + pub fn cbor_type(&mut self) -> Result { Ok(Type::from(self.get(0)?)) } #[inline] - fn cbor_expect_type(&mut self, t: Type) -> Result<'a, ()> { + fn cbor_expect_type(&mut self, t: Type) -> Result<()> { let t_ = self.cbor_type()?; if t_ != t { Err(Error::Expected(t, t_)) @@ -332,7 +321,7 @@ impl<'a> Deserializer<'a> { /// ``` /// #[inline] - pub fn cbor_len(&mut self) -> Result<'a, (Len, usize)> { + pub fn cbor_len(&mut self) -> Result<(Len, usize)> { let b: u8 = self.get(0)? & 0b0001_1111; match b { 0x00..=0x17 => Ok((Len::Len(b as u64), 0)), @@ -354,7 +343,7 @@ impl<'a> Deserializer<'a> { /// /// [`LenSz`]: ../enum.LenSz.html #[inline] - pub fn cbor_len_sz(&mut self) -> Result<'a, LenSz> { + pub fn cbor_len_sz(&mut self) -> Result { let b: u8 = self.get(0)? & 0b0001_1111; match b { 0x00..=0x17 => Ok(LenSz::Len(b as u64, Sz::Inline)), @@ -373,7 +362,7 @@ impl<'a> Deserializer<'a> { /// consume the given `len` from the underlying buffer #[inline] - pub fn advance(&mut self, len: usize) -> Result<'a, ()> { + pub fn advance(&mut self, len: usize) -> Result<()> { self.pos += len; Ok(()) @@ -385,7 +374,7 @@ impl<'a> Deserializer<'a> { } #[inline] - pub fn seek(&mut self, pos: usize) -> Result<'a, ()> { + pub fn seek(&mut self, pos: usize) -> Result<()> { if pos > self.data.len() { Err(Error::NotEnough(self.data.len(), pos)) } else { @@ -420,14 +409,14 @@ impl<'a> Deserializer<'a> { /// // the following line will panic: /// let integer = raw.unsigned_integer().unwrap(); /// ``` - pub fn unsigned_integer(&mut self) -> Result<'a, u64> { + pub fn unsigned_integer(&mut self) -> Result { Ok(self.unsigned_integer_sz()?.0) } /// Read an `UnsignedInteger` from the `Deserializer` with encoding information /// /// Same as `unsigned_integer` but returns the `Sz` (bytes used) in the encoding - pub fn unsigned_integer_sz(&mut self) -> Result<'a, (u64, Sz)> { + pub fn unsigned_integer_sz(&mut self) -> Result<(u64, Sz)> { self.cbor_expect_type(Type::UnsignedInteger)?; let len_sz = self.cbor_len_sz()?; match len_sz { @@ -455,7 +444,7 @@ impl<'a> Deserializer<'a> { /// /// assert_eq!(integer, -42); /// ``` - pub fn negative_integer(&mut self) -> Result<'a, i64> { + pub fn negative_integer(&mut self) -> Result { self.cbor_expect_type(Type::NegativeInteger)?; let (len, len_sz) = self.cbor_len()?; match len { @@ -472,7 +461,7 @@ impl<'a> Deserializer<'a> { /// Same as `negative_integer` but returns the `Sz` (bytes used) /// in the encoding as well as using a `i128` return type as `i64` /// does not cover the entire CBOR `nint` range. - pub fn negative_integer_sz(&mut self) -> Result<'a, (i128, Sz)> { + pub fn negative_integer_sz(&mut self) -> Result<(i128, Sz)> { self.cbor_expect_type(Type::NegativeInteger)?; let len_sz = self.cbor_len_sz()?; match len_sz { @@ -498,22 +487,17 @@ impl<'a> Deserializer<'a> { /// /// let bytes = raw.bytes().unwrap(); /// ``` - pub fn bytes(&mut self) -> Result<'a, &'a [u8]> { + pub fn bytes(&mut self) -> Result<&'a [u8]> { Ok(self.bytes_sz(None)?.0) } /// Read a Bytes from the Deserializer with encoding information /// /// Same as `bytes` but also returns `StringLenSz` for details about the encoding used. - #[cfg(feature = "alloc")] - pub fn bytes_sz_vec(&mut self) -> Result<'a, (&'a [u8], StringLenSz)> { - self.bytes_sz(Some(|len| Vec::with_capacity(len).as_mut_slice())) - } - pub fn bytes_sz( &mut self, sz_alloc: Option &'a mut [(u64, Sz)]>, - ) -> Result<'a, (&'a [u8], StringLenSz)> { + ) -> Result<(&'a [u8], StringLenSz)> { self.cbor_expect_type(Type::Bytes)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; @@ -589,22 +573,17 @@ impl<'a> Deserializer<'a> { /// /// assert!(&*text == "text"); /// ``` - pub fn text(&mut self) -> Result<'a, &'a str> { + pub fn text(&mut self) -> Result<&'a str> { Ok(self.text_sz(None)?.0) } /// Read a Text from the Deserializer with encoding information /// /// Same as `text` but also returns `StringLenSz` for details about the encoding used. - #[cfg(feature = "alloc")] - pub fn text_sz_vec(&mut self) -> Result<'a, (&'a str, StringLenSz)> { - self.text_sz(Some(|len| Vec::with_capacity(len).as_mut_slice())) - } - pub fn text_sz( &mut self, sz_alloc: Option &'a mut [(u64, Sz)]>, - ) -> Result<'a, (&'a str, StringLenSz)> { + ) -> Result<(&'a str, StringLenSz)> { self.cbor_expect_type(Type::Text)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; @@ -672,9 +651,9 @@ impl<'a> Deserializer<'a> { // Internal helper to decode a series of `len` items using a function. If // `len` is indefinite, decode until a `Special::Break`. If `len` is // definite, decode that many items. - fn internal_items_with(&mut self, len: Len, mut f: F) -> Result<'a, ()> + fn internal_items_with(&mut self, len: Len, mut f: F) -> Result<()> where - F: FnMut(&mut Self) -> Result<'a, ()>, + F: FnMut(&mut Self) -> Result<()>, { match len { Len::Indefinite => { @@ -708,7 +687,7 @@ impl<'a> Deserializer<'a> { /// assert_eq!(len, Len::Len(6)); /// ``` /// - pub fn array(&mut self) -> Result<'a, Len> { + pub fn array(&mut self) -> Result { self.cbor_expect_type(Type::Array)?; let (len, sz) = self.cbor_len()?; self.advance(1 + sz)?; @@ -719,7 +698,7 @@ impl<'a> Deserializer<'a> { /// /// Same as `array` but returns the `LenSz` instead which contains /// additional information about the encoding used for the length - pub fn array_sz(&mut self) -> Result<'a, LenSz> { + pub fn array_sz(&mut self) -> Result { self.cbor_expect_type(Type::Array)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; @@ -731,16 +710,16 @@ impl<'a> Deserializer<'a> { /// This works with either definite or indefinite arrays. Each call to the /// function should decode one item. If the function returns an error, /// decoding stops and returns that error. - pub fn array_with(&mut self, f: F) -> Result<'a, ()> + pub fn array_with(&mut self, f: F) -> Result<()> where - F: FnMut(&mut Self) -> Result<'a, ()>, + F: FnMut(&mut Self) -> Result<()>, { let len = self.array()?; self.internal_items_with(len, f) } /// Expect an array of a specified length. Must be a definite-length array. - pub fn tuple(&mut self, expected_len: u64, error_location: &'static str) -> Result<'a, ()> { + pub fn tuple(&mut self, expected_len: u64, error_location: &'static str) -> Result<()> { let actual_len = self.array()?; match actual_len { Len::Len(len) if expected_len == len => Ok(()), @@ -765,7 +744,7 @@ impl<'a> Deserializer<'a> { /// assert_eq!(len, Len::Len(2)); /// ``` /// - pub fn map(&mut self) -> Result<'a, Len> { + pub fn map(&mut self) -> Result { self.cbor_expect_type(Type::Map)?; let (len, sz) = self.cbor_len()?; self.advance(1 + sz)?; @@ -776,7 +755,7 @@ impl<'a> Deserializer<'a> { /// /// Same as `map` but returns the `LenSz` instead which contains /// additional information about the encoding used for the length - pub fn map_sz(&mut self) -> Result<'a, LenSz> { + pub fn map_sz(&mut self) -> Result { self.cbor_expect_type(Type::Map)?; let len_sz = self.cbor_len_sz()?; self.advance(1 + len_sz.bytes_following())?; @@ -788,9 +767,9 @@ impl<'a> Deserializer<'a> { /// This works with either definite or indefinite maps. Each call to the /// function should decode one key followed by one value. If the function /// returns an error, decoding stops and returns that error. - pub fn map_with(&mut self, f: F) -> Result<'a, ()> + pub fn map_with(&mut self, f: F) -> Result<()> where - F: FnMut(&mut Self) -> Result<'a, ()>, + F: FnMut(&mut Self) -> Result<()>, { let len = self.map()?; self.internal_items_with(len, f) @@ -814,14 +793,14 @@ impl<'a> Deserializer<'a> { /// assert_eq!("text", &*raw.text().unwrap()); /// ``` /// - pub fn tag(&mut self) -> Result<'a, u64> { + pub fn tag(&mut self) -> Result { Ok(self.tag_sz()?.0) } /// CBOR Tag with encoding information /// /// Same as `tag` but returns the `Sz` (bytes used) in the encoding - pub fn tag_sz(&mut self) -> Result<'a, (u64, Sz)> { + pub fn tag_sz(&mut self) -> Result<(u64, Sz)> { self.cbor_expect_type(Type::Tag)?; match self.cbor_len_sz()? { LenSz::Indefinite => Err(Error::IndefiniteLenNotSupported(Type::Tag)), @@ -832,7 +811,7 @@ impl<'a> Deserializer<'a> { } } - pub fn set_tag(&mut self) -> Result<'a, ()> { + pub fn set_tag(&mut self) -> Result<()> { let tag = self.tag()?; if tag != 258 { return Err(Error::ExpectedSetTag); @@ -845,7 +824,7 @@ impl<'a> Deserializer<'a> { /// /// Useful when decoding a variable-length array or map where the items may themselves use /// `Special`, such as bool values. - pub fn special_break(&mut self) -> Result<'a, bool> { + pub fn special_break(&mut self) -> Result { self.cbor_expect_type(Type::Special)?; let b = self.get(0)? & 0b0001_1111; if b == 0x1f { @@ -856,7 +835,7 @@ impl<'a> Deserializer<'a> { } } - pub fn special(&mut self) -> Result<'a, Special> { + pub fn special(&mut self) -> Result { self.cbor_expect_type(Type::Special)?; let b = self.get(0)? & 0b0001_1111; match b { @@ -912,15 +891,15 @@ impl<'a> Deserializer<'a> { } } - pub fn bool(&mut self) -> Result<'a, bool> { + pub fn bool(&mut self) -> Result { self.special()?.unwrap_bool() } - pub fn float(&mut self) -> Result<'a, f64> { + pub fn float(&mut self) -> Result { self.special()?.unwrap_float() } - pub fn deserialize(&mut self) -> Result<'a, T> + pub fn deserialize(&mut self) -> Result where T: Deserialize<'a>, { @@ -929,7 +908,7 @@ impl<'a> Deserializer<'a> { /// Deserialize a value of type `T` and check that there is no /// trailing data. - pub fn deserialize_complete(&mut self) -> Result<'a, T> + pub fn deserialize_complete(&mut self) -> Result where T: Deserialize<'a>, { @@ -948,7 +927,7 @@ macro_rules! deserialize_array { ( $( $x:expr ),* ) => { $( impl<'a> Deserialize<'a> for [u8; $x] { - fn deserialize(raw: &mut Deserializer<'a>) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { let mut bytes = [0u8; $x]; let len = raw.array()?; diff --git a/src/error.rs b/src/error.rs index 6482960..c0d2a92 100644 --- a/src/error.rs +++ b/src/error.rs @@ -6,7 +6,7 @@ use types::Type; /// all expected error for cbor parsing and serialising #[derive(Debug)] -pub enum Error<'a> { +pub enum Error { ExpectedU8, ExpectedU16, ExpectedU32, @@ -27,7 +27,7 @@ pub enum Error<'a> { IndefiniteLenNotSupported(Type), WrongLen(u64, len::Len, &'static str), InvalidTextError(Utf8Error), - CannotParse(Type, &'a [u8]), + CannotParse(Type, &'static [u8]), TrailingData, InvalidIndefiniteString, InvalidLenPassed(len::Sz), @@ -35,15 +35,15 @@ pub enum Error<'a> { NoAllocator, - CustomError(&'a str), + CustomError(&'static str), } -impl From for Error<'_> { +impl From for Error { fn from(e: Utf8Error) -> Self { Error::InvalidTextError(e) } } -impl fmt::Display for Error<'_> { +impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use Error::*; match self { diff --git a/src/lib.rs b/src/lib.rs index 3aa6f75..4a5ddab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,14 +102,13 @@ pub fn test_encode_decode< >( v: &'c V, data: &'c mut [u8], -) -> Result<'b, bool> { +) -> Result { let mut se = se::Serializer::new(data); - v.serialize(&mut se) - .map_err(|e| Error::CustomError("FAIL!"))?; + v.serialize(&mut se)?; let bytes = se.finalize(); let mut raw = de::Deserializer::from(bytes); - let v_ = Deserialize::deserialize(&mut raw).map_err(|e| Error::CustomError("FAIL!"))?; + let v_ = Deserialize::deserialize(&mut raw)?; Ok(v == &v_) } diff --git a/src/result.rs b/src/result.rs index 58b04e4..43ed212 100644 --- a/src/result.rs +++ b/src/result.rs @@ -1,4 +1,4 @@ use Error; /// `Result` type for CBOR serialisation and deserialisation. -pub type Result<'a, T> = core::result::Result>; +pub type Result = core::result::Result; diff --git a/src/se.rs b/src/se.rs index 83f4b2b..83d7124 100644 --- a/src/se.rs +++ b/src/se.rs @@ -14,86 +14,59 @@ pub trait Serialize { fn serialize<'a>( &'a self, serializer: &'a mut Serializer<'a>, - ) -> Result<'a, &'a mut Serializer<'a>>; + ) -> Result<&'a mut Serializer<'a>>; } impl<'a, T: Serialize> Serialize for &'a T { fn serialize<'se>( &'se self, serializer: &'se mut Serializer<'se>, - ) -> Result<'se, &'se mut Serializer<'se>> { + ) -> Result<&'se mut Serializer<'se>> { serializer.serialize(*self) } } impl Serialize for u64 { - fn serialize<'a>( - &self, - serializer: &'a mut Serializer<'a>, - ) -> Result<'a, &'a mut Serializer<'a>> { + fn serialize<'a>(&self, serializer: &'a mut Serializer<'a>) -> Result<&'a mut Serializer<'a>> { serializer.write_unsigned_integer(*self) } } impl Serialize for u32 { - fn serialize<'a>( - &self, - serializer: &'a mut Serializer<'a>, - ) -> Result<'a, &'a mut Serializer<'a>> { + fn serialize<'a>(&self, serializer: &'a mut Serializer<'a>) -> Result<&'a mut Serializer<'a>> { serializer.write_unsigned_integer((*self) as u64) } } impl Serialize for u16 { - fn serialize<'a>( - &self, - serializer: &'a mut Serializer<'a>, - ) -> Result<'a, &'a mut Serializer<'a>> { + fn serialize<'a>(&self, serializer: &'a mut Serializer<'a>) -> Result<&'a mut Serializer<'a>> { serializer.write_unsigned_integer((*self) as u64) } } impl Serialize for u8 { - fn serialize<'a>( - &self, - serializer: &'a mut Serializer<'a>, - ) -> Result<'a, &'a mut Serializer<'a>> { + fn serialize<'a>(&self, serializer: &'a mut Serializer<'a>) -> Result<&'a mut Serializer<'a>> { serializer.write_unsigned_integer((*self) as u64) } } impl Serialize for bool { - fn serialize<'a>( - &self, - serializer: &'a mut Serializer<'a>, - ) -> Result<'a, &'a mut Serializer<'a>> { + fn serialize<'a>(&self, serializer: &'a mut Serializer<'a>) -> Result<&'a mut Serializer<'a>> { serializer.write_special(Special::Bool(*self)) } } impl Serialize for f32 { - fn serialize<'a>( - &self, - serializer: &'a mut Serializer<'a>, - ) -> Result<'a, &'a mut Serializer<'a>> { + fn serialize<'a>(&self, serializer: &'a mut Serializer<'a>) -> Result<&'a mut Serializer<'a>> { serializer.write_special(Special::Float((*self) as f64)) } } impl Serialize for f64 { - fn serialize<'a>( - &self, - serializer: &'a mut Serializer<'a>, - ) -> Result<'a, &'a mut Serializer<'a>> { + fn serialize<'a>(&self, serializer: &'a mut Serializer<'a>) -> Result<&'a mut Serializer<'a>> { serializer.write_special(Special::Float(*self)) } } #[cfg(feature = "alloc")] impl Serialize for String { - fn serialize<'a>( - &self, - serializer: &'a mut Serializer<'a>, - ) -> Result<'a, &'a mut Serializer<'a>> { + fn serialize<'a>(&self, serializer: &'a mut Serializer<'a>) -> Result<&'a mut Serializer<'a>> { serializer.write_text(self) } } impl<'b> Serialize for &'b [u8] { - fn serialize<'a>( - &self, - serializer: &'a mut Serializer<'a>, - ) -> Result<'a, &'a mut Serializer<'a>> { + fn serialize<'a>(&self, serializer: &'a mut Serializer<'a>) -> Result<&'a mut Serializer<'a>> { serializer.write_bytes(self) } } @@ -105,7 +78,7 @@ where fn serialize<'b>( &'b self, serializer: &'b mut Serializer<'b>, - ) -> Result<'b, &'b mut Serializer<'b>> { + ) -> Result<&'b mut Serializer<'b>> { serializer .write_array(Len::Len(2))? .serialize(self.0)? @@ -121,7 +94,7 @@ where fn serialize<'b>( &'b self, serializer: &'b mut Serializer<'b>, - ) -> Result<'b, &'b mut Serializer<'b>> { + ) -> Result<&'b mut Serializer<'b>> { serializer .write_array(Len::Len(3))? .serialize(self.0)? @@ -137,7 +110,7 @@ where fn serialize<'a>( &'a self, serializer: &'a mut Serializer<'a>, - ) -> Result<'a, &'a mut Serializer<'a>> { + ) -> Result<&'a mut Serializer<'a>> { match self { None => serializer.write_array(Len::Len(0)), Some(x) => serializer.write_array(Len::Len(1))?.serialize(x), @@ -152,7 +125,7 @@ where pub fn serialize_fixed_map<'a, C, K, V, W>( data: C, serializer: &'a mut Serializer<'a>, -) -> Result<'a, &'a mut Serializer<'a>> +) -> Result<&'a mut Serializer<'a>> where K: 'a + Serialize, V: 'a + Serialize, @@ -173,7 +146,7 @@ where pub fn serialize_fixed_array<'a, C, T>( data: C, serializer: &'a mut Serializer<'a>, -) -> Result<'a, &'a mut Serializer<'a>> +) -> Result<&'a mut Serializer<'a>> where T: 'a + Serialize, C: Iterator + ExactSizeIterator, @@ -190,7 +163,7 @@ where pub fn serialize_indefinite_map<'a, C, K, V, W>( data: C, serializer: &'a mut Serializer<'a>, -) -> Result<'a, &'a mut Serializer<'a>> +) -> Result<&'a mut Serializer<'a>> where K: 'a + Serialize, V: 'a + Serialize, @@ -209,7 +182,7 @@ where pub fn serialize_indefinite_array<'a, C, T, W>( data: C, serializer: &'a mut Serializer<'a>, -) -> Result<'a, &'a mut Serializer<'a>> +) -> Result<&'a mut Serializer<'a>> where T: 'a + Serialize, C: Iterator, @@ -231,47 +204,24 @@ where /// /// ``` /// # use cbor_event::se::{Serializer, Serialize}; -/// let mut serializer = Serializer::new_vec(); -/// let mut se = Serializer::new_vec(); +/// let mut serializer = Serializer::new(); +/// let mut se = Serializer::new(); /// 0u32.serialize(&mut se).unwrap(); /// serializer.write_bytes(&se.finalize()).unwrap(); /// ``` /// -#[cfg(feature = "alloc")] -pub fn serialize_cbor_in_cbor_vec<'a, T>( - data: T, - serializer: &'a mut Serializer<'a>, -) -> Result<'a, &'a mut Serializer<'a>> -where - T: Serialize, -{ - serialize_cbor_in_cbor( - data, - serializer, - Vec::with_capacity(DEFAULT_CAPACITY).as_mut_slice(), - ) -} - #[cfg(feature = "alloc")] pub fn serialize_cbor_in_cbor<'a, T>( data: T, serializer: &'a mut Serializer<'a>, buffer: &'a mut [u8], -) -> Result<'a, &'a mut Serializer<'a>> +) -> Result<&'a mut Serializer<'a>> where T: Serialize + 'a, { let mut se = Serializer::new(buffer); - { - let _ = match data - .serialize(&mut se) - .map_err(|_| Error::CustomError("Failed to serialise")) - { - Ok(_) => {} - Err(e) => return Err(e), - }; - } - serializer.write_bytes(&se.finalize()) + data.serialize(&mut se)?; + serializer.write_bytes(se.finalize()) } // use a default capacity when allocating the Serializer to avoid small reallocation @@ -305,15 +255,9 @@ impl<'a> Serializer<'a> { /// /// ``` /// use cbor_event::se::{Serializer}; - /// - /// let serializer = Serializer::new_vec(); + /// let mut vec = vec![]; + /// let serializer = Serializer::new(vec.as_mut_slice()); /// ``` - #[cfg(feature = "alloc")] - #[inline] - pub fn new_vec() -> Self { - Serializer::new(Vec::with_capacity(DEFAULT_CAPACITY).as_mut_slice()) - } - #[inline] pub fn new(w: &'a mut [u8]) -> Self { Serializer { data: w, pos: 0 } @@ -324,7 +268,7 @@ impl<'a> Serializer<'a> { /// ``` /// use cbor_event::se::{Serializer}; /// - /// let serializer = Serializer::new_vec(); + /// let serializer = Serializer::new(); /// /// let bytes = serializer.finalize(); /// @@ -429,7 +373,7 @@ impl<'a> Serializer<'a> { /// ``` /// use cbor_event::se::{Serializer}; /// - /// let mut serializer = Serializer::new_vec(); + /// let mut serializer = Serializer::new(); /// serializer.write_unsigned_integer(0x12) /// .expect("write a negative integer"); /// @@ -454,7 +398,7 @@ impl<'a> Serializer<'a> { /// ``` /// use cbor_event::se::{Serializer}; /// - /// let mut serializer = Serializer::new_vec(); + /// let mut serializer = Serializer::new(); /// serializer.write_negative_integer(-12) /// .expect("write a negative integer"); /// @@ -482,7 +426,7 @@ impl<'a> Serializer<'a> { /// ``` /// use cbor_event::se::{Serializer}; /// - /// let mut serializer = Serializer::new_vec(); + /// let mut serializer = Serializer::new(); /// serializer.write_bytes(vec![0,1,2,3]) /// .expect("write bytes"); /// @@ -538,7 +482,7 @@ impl<'a> Serializer<'a> { /// ``` /// use cbor_event::se::{Serializer}; /// - /// let mut serializer = Serializer::new_vec(); + /// let mut serializer = Serializer::new(); /// serializer.write_text(r"hello world") /// .expect("write text"); /// @@ -596,7 +540,7 @@ impl<'a> Serializer<'a> { /// ``` /// use cbor_event::{se::{Serializer}, Len}; /// - /// let mut serializer = Serializer::new_vec(); + /// let mut serializer = Serializer::new(); /// serializer /// .write_array(Len::Len(2)).expect("write an array") /// .write_text(r"hello").expect("write text") @@ -609,7 +553,7 @@ impl<'a> Serializer<'a> { /// ``` /// use cbor_event::{se::{Serializer}, Len, Special}; /// - /// let mut serializer = Serializer::new_vec(); + /// let mut serializer = Serializer::new(); /// serializer /// .write_array(Len::Indefinite).expect("write an array") /// .write_text(r"hello").expect("write text") @@ -656,7 +600,7 @@ impl<'a> Serializer<'a> { /// ``` /// use cbor_event::{se::{Serializer}, Len}; /// - /// let mut serializer = Serializer::new_vec(); + /// let mut serializer = Serializer::new(); /// serializer /// .write_map(Len::Len(2)).expect("write a map") /// .write_unsigned_integer(1).expect("write unsigned integer") @@ -671,7 +615,7 @@ impl<'a> Serializer<'a> { /// ``` /// use cbor_event::{se::{Serializer}, Len, Special}; /// - /// let mut serializer = Serializer::new_vec(); + /// let mut serializer = Serializer::new(); /// serializer /// .write_map(Len::Indefinite).expect("write a map") /// .write_unsigned_integer(1).expect("write unsigned integer") @@ -711,7 +655,7 @@ impl<'a> Serializer<'a> { /// ``` /// use cbor_event::{se::{Serializer}, Len}; /// - /// let mut serializer = Serializer::new_vec(); + /// let mut serializer = Serializer::new(); /// serializer /// .write_tag(24).expect("write a tag") /// .write_text(r"hello").expect("write text"); @@ -744,7 +688,7 @@ impl<'a> Serializer<'a> { /// ``` /// use cbor_event::{se::{Serializer}, Len, Special}; /// - /// let mut serializer = Serializer::new_vec(); + /// let mut serializer = Serializer::new(); /// serializer /// .write_array(Len::Indefinite).expect("write an array") /// .write_special(Special::Bool(false)).expect("write false") @@ -788,7 +732,7 @@ macro_rules! serialize_array { fn serialize<'b>( &'b self, serializer: &'b mut Serializer<'b>, - ) -> Result<'b, &'b mut Serializer<'b>> { + ) -> Result<&'b mut Serializer<'b>> { serialize_fixed_array(self.iter(), serializer) } } @@ -811,7 +755,8 @@ mod test { #[test] fn unsigned_integer_0() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_unsigned_integer(0x12) .expect("write unsigned integer"); @@ -821,7 +766,8 @@ mod test { #[test] fn unsigned_integer_1() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_unsigned_integer(0x20) .expect("write unsigned integer"); @@ -831,7 +777,8 @@ mod test { #[test] fn unsigned_integer_2() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_unsigned_integer(0x2021) .expect("write unsigned integer"); @@ -841,7 +788,8 @@ mod test { #[test] fn unsigned_integer_3() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_unsigned_integer(0x20212223) .expect("write unsigned integer"); @@ -851,7 +799,8 @@ mod test { #[test] fn unsigned_integer_4() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_unsigned_integer(0x2021222324252627) .expect("write unsigned integer"); @@ -864,7 +813,8 @@ mod test { #[test] fn negative_integer_0() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_negative_integer(-12) .expect("write unsigned integer"); @@ -874,7 +824,8 @@ mod test { #[test] fn negative_integer_1() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_negative_integer(-200) .expect("write unsigned integer"); @@ -884,7 +835,8 @@ mod test { #[test] fn negative_integer_2() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_negative_integer(-13201) .expect("write unsigned integer"); @@ -894,7 +846,8 @@ mod test { #[test] fn negative_integer_3() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_negative_integer(-13201782) .expect("write unsigned integer"); @@ -904,7 +857,8 @@ mod test { #[test] fn negative_integer_4() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_negative_integer(-9902201782) .expect("write unsigned integer"); @@ -917,7 +871,8 @@ mod test { #[test] fn bytes_0() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_bytes(&vec![]) .expect("write unsigned integer"); @@ -927,7 +882,8 @@ mod test { #[test] fn bytes_1() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_bytes(&vec![0b101010]) .expect("write unsigned integer"); @@ -936,7 +892,8 @@ mod test { } fn test_special(cbor_type: Special, result: &[u8]) -> bool { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_special(cbor_type) .expect("serialize a special"); @@ -1003,7 +960,8 @@ mod test { 0x09, 0x18, 0x09, 0x19, 0x00, 0x09, 0x1a, 0x00, 0x00, 0x00, 0x09, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, ]; - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_unsigned_integer_sz(9, Sz::Inline) .unwrap() @@ -1025,7 +983,8 @@ mod test { 0x28, 0x38, 0x08, 0x39, 0x00, 0x08, 0x3a, 0x00, 0x00, 0x00, 0x08, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, ]; - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_negative_integer_sz(-9, Sz::Inline) .unwrap() @@ -1077,7 +1036,8 @@ mod test { (2, Sz::Four), (2, Sz::Eight), ]; - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_bytes_sz(vec![0xBA, 0xAD, 0xF0, 0x0D], StringLenSz::Len(Sz::Inline)) .unwrap() @@ -1122,7 +1082,8 @@ mod test { (1, Sz::Four), (3, Sz::Eight), ]; - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_text_sz("Hello", StringLenSz::Len(Sz::Inline)) .unwrap() @@ -1146,7 +1107,8 @@ mod test { 0x80, 0x98, 0x01, 0x99, 0x00, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x03, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x9f, ]; - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_array_sz(LenSz::Len(0, Sz::Inline)) .unwrap() @@ -1170,7 +1132,8 @@ mod test { 0xa0, 0xb8, 0x01, 0xb9, 0x00, 0x02, 0xba, 0x00, 0x00, 0x00, 0x03, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xbf, ]; - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_map_sz(LenSz::Len(0, Sz::Inline)) .unwrap() @@ -1194,7 +1157,8 @@ mod test { 0x09, 0x18, 0x09, 0x19, 0x00, 0x09, 0x1a, 0x00, 0x00, 0x00, 0x09, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, ]; - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); serializer .write_unsigned_integer_sz(9, Sz::Inline) .unwrap() @@ -1212,7 +1176,8 @@ mod test { #[test] fn write_type_doesnt_fit() { - let mut serializer = Serializer::new_vec(); + let mut vec = vec![]; + let mut serializer = Serializer::new(vec.as_mut_slice()); assert!(serializer .write_type_definite(Type::UnsignedInteger, 23, Some(Sz::Inline)) .is_ok()); diff --git a/src/types.rs b/src/types.rs index 21a3b77..4f8af5d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -68,7 +68,7 @@ pub enum Special { } impl Special { #[inline] - pub fn unwrap_bool(self) -> Result<'static, bool> { + pub fn unwrap_bool(self) -> Result { match self { Special::Bool(b) => Ok(b), _ => Err(Error::CustomError( @@ -80,7 +80,7 @@ impl Special { } #[inline] - pub fn unwrap_null(self) -> Result<'static, ()> { + pub fn unwrap_null(self) -> Result<()> { match self { Special::Null => Ok(()), _ => Err(Error::CustomError( @@ -92,7 +92,7 @@ impl Special { } #[inline] - pub fn unwrap_undefined(self) -> Result<'static, ()> { + pub fn unwrap_undefined(self) -> Result<()> { match self { Special::Undefined => Ok(()), _ => Err(Error::CustomError( @@ -104,7 +104,7 @@ impl Special { } #[inline] - pub fn unwrap_unassigned(self) -> Result<'static, u8> { + pub fn unwrap_unassigned(self) -> Result { match self { Special::Unassigned(v) => Ok(v), _ => Err(Error::CustomError( @@ -116,7 +116,7 @@ impl Special { } #[inline] - pub fn unwrap_float(self) -> Result<'static, f64> { + pub fn unwrap_float(self) -> Result { match self { Special::Float(f) => Ok(f), _ => Err(Error::CustomError( @@ -128,7 +128,7 @@ impl Special { } #[inline] - pub fn unwrap_break(self) -> Result<'static, ()> { + pub fn unwrap_break(self) -> Result<()> { match self { Special::Break => Ok(()), _ => Err(Error::CustomError( diff --git a/src/value.rs b/src/value.rs index acbba95..34b1e05 100644 --- a/src/value.rs +++ b/src/value.rs @@ -55,7 +55,7 @@ impl<'a> Serialize for ObjectKey { fn serialize<'se>( &self, serializer: &'se mut Serializer<'se>, - ) -> Result<'se, &'se mut Serializer<'se>> { + ) -> Result<&'se mut Serializer<'se>> { match self { ObjectKey::Integer(ref v) => serializer.write_unsigned_integer(*v), ObjectKey::Bytes(ref v) => serializer.write_bytes(v), @@ -65,7 +65,7 @@ impl<'a> Serialize for ObjectKey { } #[cfg(feature = "alloc")] impl<'a> Deserialize<'a> for ObjectKey { - fn deserialize(raw: &'a mut Deserializer) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { match raw.cbor_type()? { Type::UnsignedInteger => Ok(ObjectKey::Integer(raw.unsigned_integer()?)), Type::Bytes => Ok(ObjectKey::Bytes(raw.bytes()?.to_vec())), @@ -102,7 +102,10 @@ pub enum Value { #[cfg(feature = "alloc")] impl Serialize for Value { - fn serialize<'se>(&self, serializer: &'se mut Serializer) -> Result<&'se mut Serializer> { + fn serialize<'se>( + &'se self, + serializer: &'se mut Serializer<'se>, + ) -> Result<&'se mut Serializer> { match self { Value::U64(ref v) => serializer.write_unsigned_integer(*v), Value::I64(ref v) => serializer.write_negative_integer(*v), @@ -143,7 +146,7 @@ impl Serialize for Value { } #[cfg(feature = "alloc")] impl<'a> Deserialize<'a> for Value { - fn deserialize(raw: &'a mut Deserializer) -> Result<'a, Self> { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { match raw.cbor_type()? { Type::UnsignedInteger => Ok(Value::U64(raw.unsigned_integer()?)), Type::NegativeInteger => Ok(Value::I64(raw.negative_integer()?)), From a945de49658abf318223616939b97276d3d8e04d Mon Sep 17 00:00:00 2001 From: SimonIT Date: Tue, 23 Apr 2024 00:08:20 +0200 Subject: [PATCH 10/11] Remove reference to array element --- src/value.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/value.rs b/src/value.rs index 34b1e05..1252542 100644 --- a/src/value.rs +++ b/src/value.rs @@ -114,14 +114,14 @@ impl Serialize for Value { Value::Array(ref v) => { let mut s = serializer.write_array(Len::Len(v.len() as u64))?; for element in v { - s = s.serialize(&element)?; + s = s.serialize(element)?; } Ok(s) } Value::IArray(ref v) => { let mut s = serializer.write_array(Len::Indefinite)?; for element in v { - s = s.serialize(&element)?; + s = s.serialize(element)?; } s.write_special(Special::Break) } From fcedcca3b89a990fdc28d5425494caafd18a8720 Mon Sep 17 00:00:00 2001 From: SimonIT Date: Thu, 25 Apr 2024 23:58:24 +0200 Subject: [PATCH 11/11] Fix some errors --- src/lib.rs | 15 ++++-------- src/se.rs | 5 ++-- src/value.rs | 66 ++++++++++++++++++++++++++-------------------------- 3 files changed, 39 insertions(+), 47 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4a5ddab..dc969f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -93,19 +93,12 @@ const CBOR_PAYLOAD_LENGTH_U64: u8 = 27; /// [`Deserialize`](./de/trait.Deserialize.html). /// #[cfg(test)] -pub fn test_encode_decode< - 'a, - 'b, - 'c, - B: Deserialize<'c>, - V: Sized + PartialEq + Serialize + Deserialize<'a>, ->( - v: &'c V, - data: &'c mut [u8], +pub fn test_encode_decode<'a, V: Sized + PartialEq + Serialize + Deserialize<'a>>( + v: &'a V, + data: &'a mut [u8], ) -> Result { let mut se = se::Serializer::new(data); - v.serialize(&mut se)?; - let bytes = se.finalize(); + let bytes = v.serialize(&mut se)?.finalize(); let mut raw = de::Deserializer::from(bytes); let v_ = Deserialize::deserialize(&mut raw)?; diff --git a/src/se.rs b/src/se.rs index 83d7124..e8fdb0b 100644 --- a/src/se.rs +++ b/src/se.rs @@ -220,8 +220,7 @@ where T: Serialize + 'a, { let mut se = Serializer::new(buffer); - data.serialize(&mut se)?; - serializer.write_bytes(se.finalize()) + serializer.write_bytes(data.serialize(&mut se)?.finalize()) } // use a default capacity when allocating the Serializer to avoid small reallocation @@ -275,7 +274,7 @@ impl<'a> Serializer<'a> { /// # assert!(bytes.is_empty()); /// ``` #[inline] - pub fn finalize(self) -> &'a [u8] { + pub fn finalize(&'a self) -> &'a [u8] { self.data } diff --git a/src/value.rs b/src/value.rs index 1252542..4c67d46 100644 --- a/src/value.rs +++ b/src/value.rs @@ -325,49 +325,49 @@ mod test { #[test] fn u64() { - assert!(test_encode_decode(&Value::U64(0)).unwrap()); - assert!(test_encode_decode(&Value::U64(23)).unwrap()); - assert!(test_encode_decode(&Value::U64(0xff)).unwrap()); - assert!(test_encode_decode(&Value::U64(0x100)).unwrap()); - assert!(test_encode_decode(&Value::U64(0xffff)).unwrap()); - assert!(test_encode_decode(&Value::U64(0x10000)).unwrap()); - assert!(test_encode_decode(&Value::U64(0xffffffff)).unwrap()); - assert!(test_encode_decode(&Value::U64(0x100000000)).unwrap()); - assert!(test_encode_decode(&Value::U64(0xffffffffffffffff)).unwrap()); + assert!(test_encode_decode(Value::U64(0)).unwrap()); + assert!(test_encode_decode(Value::U64(23)).unwrap()); + assert!(test_encode_decode(Value::U64(0xff)).unwrap()); + assert!(test_encode_decode(Value::U64(0x100)).unwrap()); + assert!(test_encode_decode(Value::U64(0xffff)).unwrap()); + assert!(test_encode_decode(Value::U64(0x10000)).unwrap()); + assert!(test_encode_decode(Value::U64(0xffffffff)).unwrap()); + assert!(test_encode_decode(Value::U64(0x100000000)).unwrap()); + assert!(test_encode_decode(Value::U64(0xffffffffffffffff)).unwrap()); } #[test] fn i64() { - assert!(test_encode_decode(&Value::I64(0)).unwrap()); - assert!(test_encode_decode(&Value::I64(23)).unwrap()); - assert!(test_encode_decode(&Value::I64(-99)).unwrap()); - assert!(test_encode_decode(&Value::I64(99999)).unwrap()); - assert!(test_encode_decode(&Value::I64(-9999999)).unwrap()); - assert!(test_encode_decode(&Value::I64(-283749237289)).unwrap()); - assert!(test_encode_decode(&Value::I64(93892929229)).unwrap()); + assert!(test_encode_decode(Value::I64(0)).unwrap()); + assert!(test_encode_decode(Value::I64(23)).unwrap()); + assert!(test_encode_decode(Value::I64(-99)).unwrap()); + assert!(test_encode_decode(Value::I64(99999)).unwrap()); + assert!(test_encode_decode(Value::I64(-9999999)).unwrap()); + assert!(test_encode_decode(Value::I64(-283749237289)).unwrap()); + assert!(test_encode_decode(Value::I64(93892929229)).unwrap()); } #[test] fn bytes() { - assert!(test_encode_decode(&Value::Bytes(vec![])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(vec![0; 23])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(vec![0; 24])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(vec![0; 256])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(vec![0; 10293])).unwrap()); - assert!(test_encode_decode(&Value::Bytes(vec![0; 99999000])).unwrap()); + assert!(test_encode_decode(Value::Bytes(vec![])).unwrap()); + assert!(test_encode_decode(Value::Bytes(vec![0; 23])).unwrap()); + assert!(test_encode_decode(Value::Bytes(vec![0; 24])).unwrap()); + assert!(test_encode_decode(Value::Bytes(vec![0; 256])).unwrap()); + assert!(test_encode_decode(Value::Bytes(vec![0; 10293])).unwrap()); + assert!(test_encode_decode(Value::Bytes(vec![0; 99999000])).unwrap()); } #[test] fn text() { - assert!(test_encode_decode(&Value::Text("".to_owned())).unwrap()); - assert!(test_encode_decode(&Value::Text("hellow world".to_owned())).unwrap()); - assert!(test_encode_decode(&Value::Text("some sentence, some sentence... some sentence...some sentence, some sentence... some sentence...".to_owned())).unwrap()); + assert!(test_encode_decode(Value::Text("".to_owned())).unwrap()); + assert!(test_encode_decode(Value::Text("hellow world".to_owned())).unwrap()); + assert!(test_encode_decode(Value::Text("some sentence, some sentence... some sentence...some sentence, some sentence... some sentence...".to_owned())).unwrap()); } #[test] fn array() { - assert!(test_encode_decode(&Value::Array(vec![])).unwrap()); - assert!(test_encode_decode(&Value::Array(vec![ + assert!(test_encode_decode(Value::Array(vec![])).unwrap()); + assert!(test_encode_decode(Value::Array(vec![ Value::U64(0), Value::Text("some text".to_owned()) ])) @@ -376,8 +376,8 @@ mod test { #[test] fn iarray() { - assert!(test_encode_decode(&Value::IArray(vec![])).unwrap()); - assert!(test_encode_decode(&Value::IArray(vec![ + assert!(test_encode_decode(Value::IArray(vec![])).unwrap()); + assert!(test_encode_decode(Value::IArray(vec![ Value::U64(0), Value::Text("some text".to_owned()) ])) @@ -386,16 +386,16 @@ mod test { #[test] fn tag() { - assert!(test_encode_decode(&Value::Tag(23, Box::new(Value::U64(0)))).unwrap()); - assert!(test_encode_decode(&Value::Tag(24, Box::new(Value::Bytes(vec![0; 32])))).unwrap()); + assert!(test_encode_decode(Value::Tag(23, Box::new(Value::U64(0)))).unwrap()); + assert!(test_encode_decode(Value::Tag(24, Box::new(Value::Bytes(vec![0; 32])))).unwrap()); assert!( - test_encode_decode(&Value::Tag(0x1ff, Box::new(Value::Bytes(vec![0; 624])))).unwrap() + test_encode_decode(Value::Tag(0x1ff, Box::new(Value::Bytes(vec![0; 624])))).unwrap() ); } quickcheck! { fn property_encode_decode(value: Value) -> bool { - test_encode_decode(&value).unwrap() + test_encode_decode(value).unwrap() } } }