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..d5792aa 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 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; } -impl Deserialize for u8 { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a> Deserialize<'a> for u8 { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { 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 { 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 { let n = raw.unsigned_integer()?; if n > u32::MAX as u64 { Err(Error::ExpectedU32) @@ -49,38 +53,46 @@ 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 { raw.unsigned_integer() } } -impl Deserialize for bool { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a> Deserialize<'a> for bool { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { raw.bool() } } -impl Deserialize for f32 { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a> Deserialize<'a> for f32 { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { raw.float().map(|f| f as f32) } } -impl Deserialize for f64 { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a> Deserialize<'a> for f64 { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { raw.float() } } -impl Deserialize for String { - fn deserialize(raw: &mut Deserializer) -> Result { +impl<'a> Deserialize<'a> for &'a str { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { raw.text() } } -impl Deserialize for Vec { - fn deserialize(raw: &mut Deserializer) -> Result { +#[cfg(feature = "alloc")] +impl<'a> Deserialize<'a> for 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<'a>) -> Result { let mut vec = Vec::new(); raw.array_with(|raw| { vec.push(Deserialize::deserialize(raw)?); @@ -89,8 +101,9 @@ impl Deserialize for Vec { Ok(vec) } } -impl Deserialize for BTreeMap { - fn deserialize(raw: &mut Deserializer) -> Result { +#[cfg(feature = "alloc")] +impl<'a, K: Deserialize<'a> + Ord, V: Deserialize<'a>> Deserialize<'a> for BTreeMap { + fn deserialize(raw: &mut Deserializer<'a>) -> Result { let mut vec = BTreeMap::new(); raw.map_with(|raw| { let k = Deserialize::deserialize(raw)?; @@ -102,15 +115,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 { 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,50 +186,52 @@ 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, + allocate: Option &'a mut [u8]>, } -impl From> for Deserializer { - fn from(r: Vec) -> Self { - Deserializer { data: r } + +impl<'a> From<&'a [u8]> for Deserializer<'a> { + fn from(r: &'a [u8]) -> Self { + Deserializer { + data: r, + pos: 0, + allocate: None, + } } } -impl AsRef> for Deserializer { - fn as_ref(&self) -> &Vec { - &self.data +impl<'a> AsRef<[u8]> for Deserializer<'a> { + fn as_ref(&self) -> &[u8] { + self.data } } -impl Display for Deserializer { +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() + .try_for_each(|b| f.write_fmt(format_args!("{:02x}", b))) } } -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 { - match self.data.get(index) { + 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), + Some(b) => Ok(b), } } #[inline] fn u8(&mut self, index: usize) -> Result { let b = self.get(index)?; - Ok(b as u64) + Ok(*b as u64) } #[inline] fn u16(&mut self, index: usize) -> Result { @@ -344,15 +360,29 @@ impl Deserializer { } } - /// 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<()> { - self.data.drain(..len); + self.pos += len; Ok(()) } + #[inline] + pub fn position(&self) -> usize { + self.pos + } + + #[inline] + pub fn seek(&mut self, pos: usize) -> Result<()> { + 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`. @@ -457,21 +487,27 @@ impl Deserializer { /// /// let bytes = raw.bytes().unwrap(); /// ``` - pub fn bytes(&mut self) -> Result> { - Ok(self.bytes_sz()?.0) + 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. - pub fn bytes_sz(&mut self) -> Result<(Vec, StringLenSz)> { + pub fn bytes_sz( + &mut self, + sz_alloc: Option &'a mut [(u64, Sz)]>, + ) -> 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(); + 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()?; @@ -479,19 +515,44 @@ 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]); self.advance(len as usize)?; - chunk_lens.push((len, sz)); + chunks += 1; } } } - Ok((bytes, StringLenSz::Indefinite(chunk_lens))) + 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()?; + match chunk_len_sz { + LenSz::Indefinite => return Err(Error::InvalidIndefiniteString), + LenSz::Len(len, sz) => { + 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(( + bytes, + StringLenSz::Indefinite(chunk_lens.unwrap_or(&mut [])), + )) } 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 +573,27 @@ impl Deserializer { /// /// assert!(&*text == "text"); /// ``` - pub fn text(&mut self) -> Result { - Ok(self.text_sz()?.0) + 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. - pub fn text_sz(&mut self) -> Result<(String, StringLenSz)> { + pub fn text_sz( + &mut self, + sz_alloc: Option &'a mut [(u64, Sz)]>, + ) -> 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(); + 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()?; @@ -536,19 +603,45 @@ 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(); self.advance(len as usize)?; - text.push_str(&chunk_text); - chunk_lens.push((len, sz)); + chunks += 1; } } } - Ok((text, StringLenSz::Indefinite(chunk_lens))) + 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(( + core::str::from_utf8(bytes)?, + StringLenSz::Indefinite(chunk_lens.unwrap_or(&mut [])), + )) } 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))) } @@ -808,7 +901,7 @@ impl Deserializer { pub fn deserialize(&mut self) -> Result where - T: Deserialize, + T: Deserialize<'a>, { Deserialize::deserialize(self) } @@ -817,13 +910,13 @@ impl Deserializer { /// trailing data. pub fn deserialize_complete(&mut self) -> Result where - T: Deserialize, + 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) } } } @@ -833,8 +926,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 { let mut bytes = [0u8; $x]; let len = raw.array()?; @@ -869,10 +962,13 @@ 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() { - let vec = vec![0x38, 0x29]; + let vec = [0x38, 0x29].as_ref(); let mut raw = Deserializer::from(vec); let integer = raw.negative_integer().unwrap(); @@ -882,23 +978,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() { @@ -906,16 +1004,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(); @@ -924,39 +1022,42 @@ 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(); - assert_eq!(&text, "text"); + assert_eq!(text, "text"); } #[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(); - assert_eq!(&text, ""); + assert_eq!(text, ""); } #[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(); @@ -966,7 +1067,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(); @@ -976,7 +1077,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(); @@ -993,7 +1094,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(); @@ -1003,7 +1104,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(); @@ -1012,22 +1113,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]); @@ -1035,17 +1138,18 @@ 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(); 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()); @@ -1064,7 +1168,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(); @@ -1074,7 +1178,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(); @@ -1084,7 +1188,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(); @@ -1093,8 +1197,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); @@ -1102,8 +1207,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); @@ -1113,10 +1219,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(); @@ -1128,17 +1235,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(); @@ -1147,10 +1255,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)); @@ -1161,10 +1270,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)); @@ -1191,40 +1301,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 = vec![ + ] + .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().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().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().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().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().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().unwrap(), + raw.bytes_sz(None).unwrap(), (indef_bytes, StringLenSz::Indefinite(indef_lens)) ); } @@ -1249,8 +1364,8 @@ mod test { vec.extend_from_slice(&slice[..]); } vec.push(0xFF); - let mut raw = Deserializer::from(vec); - let indef_lens = vec![ + let mut raw = Deserializer::from(vec.as_slice()); + let indef_lens = &[ (5, Sz::Inline), (5, Sz::One), (9, Sz::Two), @@ -1258,27 +1373,27 @@ mod test { (3, Sz::Eight), ]; assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz(None).unwrap(), ("Hello".into(), StringLenSz::Len(Sz::Inline)) ); assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz(None).unwrap(), ("World".into(), StringLenSz::Len(Sz::One)) ); assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz(None).unwrap(), ("日本語".into(), StringLenSz::Len(Sz::Two)) ); assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz(None).unwrap(), ("9".into(), StringLenSz::Len(Sz::Four)) ); assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz(None).unwrap(), ("ABC".into(), StringLenSz::Len(Sz::Eight)) ); assert_eq!( - raw.text_sz().unwrap(), + raw.text_sz(None).unwrap(), ( "HelloWorld日本語9ABC".into(), StringLenSz::Indefinite(indef_lens) @@ -1288,10 +1403,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)); @@ -1303,10 +1419,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)); @@ -1318,10 +1435,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/error.rs b/src/error.rs index 1f0313b..c0d2a92 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,5 @@ -use alloc::string::{FromUtf8Error, String}; -use alloc::vec::Vec; use core::fmt; +use core::str::Utf8Error; use len; use types::Type; @@ -27,17 +26,19 @@ pub enum Error { UnknownLenType(u8), IndefiniteLenNotSupported(Type), WrongLen(u64, len::Len, &'static str), - InvalidTextError(FromUtf8Error), - CannotParse(Type, Vec), + InvalidTextError(Utf8Error), + CannotParse(Type, &'static [u8]), TrailingData, InvalidIndefiniteString, InvalidLenPassed(len::Sz), InvalidNint(i128), - CustomError(String), + NoAllocator, + + CustomError(&'static str), } -impl From for Error { - fn from(e: FromUtf8Error) -> Self { +impl From for Error { + fn from(e: Utf8Error) -> Self { Error::InvalidTextError(e) } } @@ -89,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 7d44323..89dbbb6 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)] -pub enum StringLenSz { - Indefinite(Vec<(u64, Sz)>), +#[derive(Debug, PartialEq, Eq)] +pub enum StringLenSz<'a> { + Indefinite(&'a [(u64, Sz)]), Len(Sz), } diff --git a/src/lib.rs b/src/lib.rs index 641b2bd..dc969f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,10 +59,18 @@ //! ``` #![no_std] +#[cfg(any(feature = "alloc", test))] +extern crate alloc; #[cfg(test)] #[macro_use] extern crate quickcheck; -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; @@ -73,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; @@ -92,10 +92,13 @@ 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 { - let mut se = se::Serializer::new_vec(); - v.serialize(&mut se)?; - let bytes = se.finalize(); +#[cfg(test)] +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); + 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 166b2a5..e8fdb0b 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; @@ -9,55 +11,62 @@ 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 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 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 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 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 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 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 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 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 mut Serializer<'a>> { serializer.write_special(Special::Float(*self)) } } +#[cfg(feature = "alloc")] 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 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 mut Serializer<'a>> { serializer.write_bytes(self) } } @@ -66,7 +75,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 mut Serializer<'b>> { serializer .write_array(Len::Len(2))? .serialize(self.0)? @@ -79,7 +91,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 mut Serializer<'b>> { serializer .write_array(Len::Len(3))? .serialize(self.0)? @@ -92,7 +107,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 mut Serializer<'a>> { match self { None => serializer.write_array(Len::Len(0)), Some(x) => serializer.write_array(Len::Len(1))?.serialize(x), @@ -106,19 +124,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 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 +145,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 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 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 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 @@ -186,19 +204,23 @@ 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(); /// ``` /// -pub fn serialize_cbor_in_cbor(data: T, serializer: &mut Serializer) -> Result<&mut Serializer> +#[cfg(feature = "alloc")] +pub fn serialize_cbor_in_cbor<'a, T>( + data: T, + serializer: &'a mut Serializer<'a>, + buffer: &'a mut [u8], +) -> Result<&'a mut Serializer<'a>> where - T: Serialize, + T: Serialize + 'a, { - let mut se = Serializer::new_vec(); - data.serialize(&mut se)?; - serializer.write_bytes(&se.finalize()) + let mut se = Serializer::new(buffer); + serializer.write_bytes(data.serialize(&mut se)?.finalize()) } // use a default capacity when allocating the Serializer to avoid small reallocation @@ -211,18 +233,20 @@ 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], + pos: usize, } -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[self.pos..self.pos + bytes.len()].copy_from_slice(bytes); + self.pos += bytes.len(); Ok(self) } @@ -230,17 +254,12 @@ impl Serializer { /// /// ``` /// use cbor_event::se::{Serializer}; - /// - /// let serializer = Serializer::new_vec(); + /// let mut vec = vec![]; + /// let serializer = Serializer::new(vec.as_mut_slice()); /// ``` #[inline] - pub fn new_vec() -> Self { - Serializer::new(Vec::with_capacity(DEFAULT_CAPACITY)) - } - - #[inline] - pub fn new(w: Vec) -> Self { - Serializer { data: w } + pub fn new(w: &'a mut [u8]) -> Self { + Serializer { data: w, pos: 0 } } /// finalize the serializer, returning the serializer bytes @@ -248,46 +267,42 @@ impl Serializer { /// ``` /// use cbor_event::se::{Serializer}; /// - /// let serializer = Serializer::new_vec(); + /// let serializer = Serializer::new(); /// /// let bytes = serializer.finalize(); /// /// # assert!(bytes.is_empty()); /// ``` #[inline] - pub fn finalize(self) -> Vec { + pub fn finalize(&'a self) -> &'a [u8] { self.data } #[inline] fn write_u8(&mut self, value: u8) -> Result<&mut Self> { - self.data.extend_from_slice(&[value][..]); - Ok(self) + self.write_raw_bytes(&[value][..]) } #[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][..]); - 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.extend_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.extend_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, @@ -298,14 +313,12 @@ impl Serializer { ((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.extend_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 @@ -359,7 +372,7 @@ impl Serializer { /// ``` /// 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"); /// @@ -384,7 +397,7 @@ impl Serializer { /// ``` /// 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"); /// @@ -412,7 +425,7 @@ impl Serializer { /// ``` /// 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"); /// @@ -423,7 +436,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.write_raw_bytes(bytes).unwrap(); s }) } @@ -441,7 +454,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.write_raw_bytes(bytes).unwrap(); s }), StringLenSz::Indefinite(lens) => { @@ -449,16 +462,16 @@ impl Serializer { 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 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) } } } @@ -468,7 +481,7 @@ impl Serializer { /// ``` /// 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"); /// @@ -478,10 +491,7 @@ impl Serializer { 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.extend_from_slice(bytes); - s - }) + .map(|s| s.write_raw_bytes(bytes).unwrap()) } /// write the given object as text using a specific string encoding @@ -492,27 +502,24 @@ impl Serializer { match sz { StringLenSz::Len(sz) => self .write_type_definite(Type::Text, bytes.len() as u64, Some(sz)) - .map(|s| { - s.data.extend_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 { 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 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))?; + 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) } } } @@ -532,7 +539,7 @@ impl Serializer { /// ``` /// 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") @@ -545,7 +552,7 @@ impl Serializer { /// ``` /// 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") @@ -592,7 +599,7 @@ impl Serializer { /// ``` /// 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") @@ -607,7 +614,7 @@ impl Serializer { /// ``` /// 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") @@ -647,7 +654,7 @@ impl Serializer { /// ``` /// 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"); @@ -680,7 +687,7 @@ impl Serializer { /// ``` /// 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") @@ -710,7 +717,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 +729,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 mut Serializer<'b>> { serialize_fixed_array(self.iter(), serializer) } } @@ -739,6 +746,7 @@ serialize_array!( ); #[cfg(test)] +#[cfg(feature = "alloc")] mod test { use super::*; use alloc::vec; @@ -746,7 +754,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"); @@ -756,7 +765,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"); @@ -766,7 +776,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"); @@ -776,7 +787,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"); @@ -786,7 +798,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"); @@ -799,7 +812,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"); @@ -809,7 +823,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"); @@ -819,7 +834,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"); @@ -829,7 +845,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"); @@ -839,7 +856,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"); @@ -852,7 +870,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"); @@ -862,7 +881,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"); @@ -871,7 +891,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"); @@ -938,7 +959,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() @@ -960,7 +982,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() @@ -998,21 +1021,22 @@ 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![ 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), (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() @@ -1047,17 +1071,18 @@ 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 = vec![ + let indef_lens = &[ (5, Sz::Inline), (5, Sz::One), (9, Sz::Two), (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() @@ -1081,7 +1106,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() @@ -1105,7 +1131,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() @@ -1129,7 +1156,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() @@ -1147,7 +1175,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 2f635d0..4f8af5d 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}; @@ -32,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, @@ -46,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) } } @@ -69,68 +68,74 @@ pub enum Special { } impl Special { #[inline] - pub fn unwrap_bool(&self) -> Result { + pub fn unwrap_bool(self) -> Result { 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(), + )), } } #[inline] - pub fn unwrap_null(&self) -> Result<()> { + 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(), + )), } } #[inline] - pub fn unwrap_undefined(&self) -> Result<()> { + 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 { 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 { 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(), + )), } } #[inline] - pub fn unwrap_break(&self) -> Result<()> { + 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(), + )), } } } @@ -157,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 954b972..4c67d46 100644 --- a/src/value.rs +++ b/src/value.rs @@ -9,10 +9,13 @@ //! //! 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 alloc::format; -use alloc::string::String; +#[cfg(feature = "alloc")] +use alloc::string::{String, ToString}; +#[cfg(feature = "alloc")] use alloc::vec::Vec; #[cfg(test)] use core::iter::repeat_with; @@ -30,11 +33,13 @@ 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)] +#[cfg(feature = "alloc")] pub enum ObjectKey { Integer(u64), Bytes(Vec), Text(String), } +#[cfg(feature = "alloc")] impl ObjectKey { /// convert the given `ObjectKey` into a CBOR [`Value`](./struct.Value.html) pub fn value(self) -> Value { @@ -45,8 +50,12 @@ impl ObjectKey { } } } -impl Serialize for ObjectKey { - fn serialize<'se>(&self, serializer: &'se mut Serializer) -> Result<&'se mut Serializer> { +#[cfg(feature = "alloc")] +impl<'a> Serialize for ObjectKey { + fn serialize<'se>( + &self, + serializer: &'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), @@ -54,16 +63,18 @@ impl Serialize for ObjectKey { } } } -impl Deserialize for ObjectKey { - fn deserialize(raw: &mut Deserializer) -> Result { +#[cfg(feature = "alloc")] +impl<'a> Deserialize<'a> for ObjectKey { + 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()?)), - Type::Text => Ok(ObjectKey::Text(raw.text()?)), - t => Err(Error::CustomError(format!( - "Type `{:?}' is not a support type for CBOR Map's key", - t - ))), + 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() + .unwrap(), + )), } } } @@ -75,6 +86,7 @@ impl Deserialize for ObjectKey { /// so. However it is handy for debugging or reverse a given protocol. /// #[derive(Debug, Clone, PartialEq, PartialOrd)] +#[cfg(feature = "alloc")] pub enum Value { U64(u64), I64(i64), @@ -88,53 +100,58 @@ pub enum Value { Special(Special), } +#[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), 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 { - 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 { - serializer.serialize(element)?; + s = s.serialize(element)?; } - serializer.write_special(Special::Break) + 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.as_ref()), Value::Special(ref v) => serializer.write_special(*v), } } } -impl Deserialize for Value { - fn deserialize(raw: &mut Deserializer) -> Result { +#[cfg(feature = "alloc")] +impl<'a> Deserialize<'a> for Value { + 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()?)), - 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(); @@ -200,6 +217,7 @@ impl Deserialize for Value { } } +#[cfg(feature = "alloc")] #[cfg(test)] impl Arbitrary for ObjectKey { fn arbitrary(g: &mut G) -> Self { @@ -212,6 +230,7 @@ impl Arbitrary for ObjectKey { } } +#[cfg(feature = "alloc")] #[cfg(test)] fn arbitrary_value_finite(g: &mut G) -> Value { match u8::arbitrary(g) % 5 { @@ -224,6 +243,7 @@ fn arbitrary_value_finite(g: &mut G) -> Value { } } +#[cfg(feature = "alloc")] #[cfg(test)] fn arbitrary_value_indefinite(counter: usize, g: &mut G) -> Value { if counter == 0 { @@ -286,6 +306,7 @@ fn arbitrary_value_indefinite(counter: usize, g: &mut G) -> Value { } } +#[cfg(feature = "alloc")] #[cfg(test)] impl Arbitrary for Value { fn arbitrary(g: &mut G) -> Self { @@ -293,6 +314,7 @@ impl Arbitrary for Value { } } +#[cfg(feature = "alloc")] #[cfg(test)] mod test { use alloc::borrow::ToOwned; @@ -303,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()) ])) @@ -354,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()) ])) @@ -364,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() } } }