diff --git a/src/de/mod.rs b/src/de/mod.rs index 11d8c2230..da89308b0 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -741,8 +741,8 @@ mod tests { #[test] fn array() { - assert_eq!(crate::from_str::<[i32; 0]>("[]"), Ok([])); - assert_eq!(crate::from_str("[0, 1, 2]"), Ok([0, 1, 2])); + assert_eq!(crate::from_str::<[i32; 0]>("[]"), Ok(([], 2))); + assert_eq!(crate::from_str("[0, 1, 2]"), Ok(([0, 1, 2], 9))); // errors assert!(crate::from_str::<[i32; 2]>("[0, 1,]").is_err()); @@ -750,13 +750,13 @@ mod tests { #[test] fn bool() { - assert_eq!(crate::from_str("true"), Ok(true)); - assert_eq!(crate::from_str(" true"), Ok(true)); - assert_eq!(crate::from_str("true "), Ok(true)); + assert_eq!(crate::from_str("true"), Ok((true, 4))); + assert_eq!(crate::from_str(" true"), Ok((true, 5))); + assert_eq!(crate::from_str("true "), Ok((true, 5))); - assert_eq!(crate::from_str("false"), Ok(false)); - assert_eq!(crate::from_str(" false"), Ok(false)); - assert_eq!(crate::from_str("false "), Ok(false)); + assert_eq!(crate::from_str("false"), Ok((false, 5))); + assert_eq!(crate::from_str(" false"), Ok((false, 6))); + assert_eq!(crate::from_str("false "), Ok((false, 6))); // errors assert!(crate::from_str::("true false").is_err()); @@ -765,42 +765,54 @@ mod tests { #[test] fn enum_clike() { - assert_eq!(crate::from_str(r#" "boolean" "#), Ok(Type::Boolean)); - assert_eq!(crate::from_str(r#" "number" "#), Ok(Type::Number)); - assert_eq!(crate::from_str(r#" "thing" "#), Ok(Type::Thing)); + assert_eq!(crate::from_str(r#" "boolean" "#), Ok((Type::Boolean, 11))); + assert_eq!(crate::from_str(r#" "number" "#), Ok((Type::Number, 10))); + assert_eq!(crate::from_str(r#" "thing" "#), Ok((Type::Thing, 9))); } #[test] fn str() { - assert_eq!(crate::from_str(r#" "hello" "#), Ok("hello")); - assert_eq!(crate::from_str(r#" "" "#), Ok("")); - assert_eq!(crate::from_str(r#" " " "#), Ok(" ")); - assert_eq!(crate::from_str(r#" "👏" "#), Ok("👏")); + assert_eq!(crate::from_str(r#" "hello" "#), Ok(("hello", 9))); + assert_eq!(crate::from_str(r#" "" "#), Ok(("", 4))); + assert_eq!(crate::from_str(r#" " " "#), Ok((" ", 5))); + assert_eq!(crate::from_str(r#" "👏" "#), Ok(("👏", 8))); // no unescaping is done (as documented as a known issue in lib.rs) - assert_eq!(crate::from_str(r#" "hel\tlo" "#), Ok("hel\\tlo")); - assert_eq!(crate::from_str(r#" "hello \\" "#), Ok("hello \\\\")); + assert_eq!(crate::from_str(r#" "hel\tlo" "#), Ok(("hel\\tlo", 11))); + assert_eq!(crate::from_str(r#" "hello \\" "#), Ok(("hello \\\\", 12))); // escaped " in the string content - assert_eq!(crate::from_str(r#" "foo\"bar" "#), Ok(r#"foo\"bar"#)); - assert_eq!(crate::from_str(r#" "foo\\\"bar" "#), Ok(r#"foo\\\"bar"#)); - assert_eq!(crate::from_str(r#" "foo\"\"bar" "#), Ok(r#"foo\"\"bar"#)); - assert_eq!(crate::from_str(r#" "\"bar" "#), Ok(r#"\"bar"#)); - assert_eq!(crate::from_str(r#" "foo\"" "#), Ok(r#"foo\""#)); - assert_eq!(crate::from_str(r#" "\"" "#), Ok(r#"\""#)); + assert_eq!(crate::from_str(r#" "foo\"bar" "#), Ok((r#"foo\"bar"#, 12))); + assert_eq!( + crate::from_str(r#" "foo\\\"bar" "#), + Ok((r#"foo\\\"bar"#, 14)) + ); + assert_eq!( + crate::from_str(r#" "foo\"\"bar" "#), + Ok((r#"foo\"\"bar"#, 14)) + ); + assert_eq!(crate::from_str(r#" "\"bar" "#), Ok((r#"\"bar"#, 9))); + assert_eq!(crate::from_str(r#" "foo\"" "#), Ok((r#"foo\""#, 9))); + assert_eq!(crate::from_str(r#" "\"" "#), Ok((r#"\""#, 6))); // non-excaped " preceded by backslashes - assert_eq!(crate::from_str(r#" "foo bar\\" "#), Ok(r#"foo bar\\"#)); - assert_eq!(crate::from_str(r#" "foo bar\\\\" "#), Ok(r#"foo bar\\\\"#)); + assert_eq!( + crate::from_str(r#" "foo bar\\" "#), + Ok((r#"foo bar\\"#, 13)) + ); + assert_eq!( + crate::from_str(r#" "foo bar\\\\" "#), + Ok((r#"foo bar\\\\"#, 15)) + ); assert_eq!( crate::from_str(r#" "foo bar\\\\\\" "#), - Ok(r#"foo bar\\\\\\"#) + Ok((r#"foo bar\\\\\\"#, 17)) ); assert_eq!( crate::from_str(r#" "foo bar\\\\\\\\" "#), - Ok(r#"foo bar\\\\\\\\"#) + Ok((r#"foo bar\\\\\\\\"#, 19)) ); - assert_eq!(crate::from_str(r#" "\\" "#), Ok(r#"\\"#)); + assert_eq!(crate::from_str(r#" "\\" "#), Ok((r#"\\"#, 6))); } #[test] @@ -810,10 +822,13 @@ mod tests { led: bool, } - assert_eq!(crate::from_str(r#"{ "led": true }"#), Ok(Led { led: true })); + assert_eq!( + crate::from_str(r#"{ "led": true }"#), + Ok((Led { led: true }, 15)) + ); assert_eq!( crate::from_str(r#"{ "led": false }"#), - Ok(Led { led: false }) + Ok((Led { led: false }, 16)) ); } @@ -826,17 +841,17 @@ mod tests { assert_eq!( crate::from_str(r#"{ "temperature": -17 }"#), - Ok(Temperature { temperature: -17 }) + Ok((Temperature { temperature: -17 }, 22)) ); assert_eq!( crate::from_str(r#"{ "temperature": -0 }"#), - Ok(Temperature { temperature: -0 }) + Ok((Temperature { temperature: -0 }, 21)) ); assert_eq!( crate::from_str(r#"{ "temperature": 0 }"#), - Ok(Temperature { temperature: 0 }) + Ok((Temperature { temperature: 0 }, 20)) ); // out of range @@ -853,33 +868,39 @@ mod tests { assert_eq!( crate::from_str(r#"{ "temperature": -17.2 }"#), - Ok(Temperature { temperature: -17.2 }) + Ok((Temperature { temperature: -17.2 }, 24)) ); assert_eq!( crate::from_str(r#"{ "temperature": -0.0 }"#), - Ok(Temperature { temperature: -0. }) + Ok((Temperature { temperature: -0. }, 23)) ); assert_eq!( crate::from_str(r#"{ "temperature": -2.1e-3 }"#), - Ok(Temperature { - temperature: -2.1e-3 - }) + Ok(( + Temperature { + temperature: -2.1e-3 + }, + 26 + )) ); assert_eq!( crate::from_str(r#"{ "temperature": -3 }"#), - Ok(Temperature { temperature: -3. }) + Ok((Temperature { temperature: -3. }, 21)) ); use core::f32; assert_eq!( crate::from_str(r#"{ "temperature": -1e500 }"#), - Ok(Temperature { - temperature: f32::NEG_INFINITY - }) + Ok(( + Temperature { + temperature: f32::NEG_INFINITY + }, + 25 + )) ); assert!(crate::from_str::(r#"{ "temperature": 1e1e1 }"#).is_err()); @@ -899,17 +920,23 @@ mod tests { assert_eq!( crate::from_str(r#"{ "description": "An ambient temperature sensor" }"#), - Ok(Property { - description: Some("An ambient temperature sensor"), - }) + Ok(( + Property { + description: Some("An ambient temperature sensor"), + }, + 50 + )) ); assert_eq!( crate::from_str(r#"{ "description": null }"#), - Ok(Property { description: None }) + Ok((Property { description: None }, 23)) ); - assert_eq!(crate::from_str(r#"{}"#), Ok(Property { description: None })); + assert_eq!( + crate::from_str(r#"{}"#), + Ok((Property { description: None }, 2)) + ); } #[test] @@ -921,12 +948,12 @@ mod tests { assert_eq!( crate::from_str(r#"{ "temperature": 20 }"#), - Ok(Temperature { temperature: 20 }) + Ok((Temperature { temperature: 20 }, 21)) ); assert_eq!( crate::from_str(r#"{ "temperature": 0 }"#), - Ok(Temperature { temperature: 0 }) + Ok((Temperature { temperature: 0 }, 20)) ); // out of range @@ -940,8 +967,8 @@ mod tests { #[derive(Debug, Deserialize, PartialEq)] struct Xy(i8, i8); - assert_eq!(crate::from_str(r#"[10, 20]"#), Ok(Xy(10, 20))); - assert_eq!(crate::from_str(r#"[10, -20]"#), Ok(Xy(10, -20))); + assert_eq!(crate::from_str(r#"[10, 20]"#), Ok((Xy(10, 20), 8))); + assert_eq!(crate::from_str(r#"[10, -20]"#), Ok((Xy(10, -20), 9))); // wrong number of args assert_eq!( @@ -960,8 +987,8 @@ mod tests { #[derive(Debug, Deserialize, PartialEq)] struct Xy(i8, i8); - assert_eq!(crate::from_str(r#"[10, 20]"#), Ok(Xy(10, 20))); - assert_eq!(crate::from_str(r#"[10, -20]"#), Ok(Xy(10, -20))); + assert_eq!(crate::from_str(r#"[10, 20]"#), Ok((Xy(10, 20), 8))); + assert_eq!(crate::from_str(r#"[10, -20]"#), Ok((Xy(10, -20), 9))); // wrong number of args assert_eq!( @@ -985,31 +1012,31 @@ mod tests { assert_eq!( crate::from_str(r#"{ "temperature": 20, "high": 80, "low": -10, "updated": true }"#), - Ok(Temperature { temperature: 20 }) + Ok((Temperature { temperature: 20 }, 62)) ); assert_eq!( crate::from_str( r#"{ "temperature": 20, "conditions": "windy", "forecast": "cloudy" }"# ), - Ok(Temperature { temperature: 20 }) + Ok((Temperature { temperature: 20 }, 66)) ); assert_eq!( crate::from_str(r#"{ "temperature": 20, "hourly_conditions": ["windy", "rainy"] }"#), - Ok(Temperature { temperature: 20 }) + Ok((Temperature { temperature: 20 }, 62)) ); assert_eq!( crate::from_str( r#"{ "temperature": 20, "source": { "station": "dock", "sensors": ["front", "back"] } }"# ), - Ok(Temperature { temperature: 20 }) + Ok((Temperature { temperature: 20 }, 84)) ); assert_eq!( crate::from_str(r#"{ "temperature": 20, "invalid": this-is-ignored }"#), - Ok(Temperature { temperature: 20 }) + Ok((Temperature { temperature: 20 }, 49)) ); assert_eq!( @@ -1107,29 +1134,32 @@ mod tests { } "# ), - Ok(Thing { - properties: Properties { - temperature: Property { - ty: Type::Number, - unit: Some("celsius"), - description: Some("An ambient temperature sensor"), - href: "/properties/temperature", - }, - humidity: Property { - ty: Type::Number, - unit: Some("percent"), - description: None, - href: "/properties/humidity", - }, - led: Property { - ty: Type::Boolean, - unit: None, - description: Some("A red LED"), - href: "/properties/led", + Ok(( + Thing { + properties: Properties { + temperature: Property { + ty: Type::Number, + unit: Some("celsius"), + description: Some("An ambient temperature sensor"), + href: "/properties/temperature", + }, + humidity: Property { + ty: Type::Number, + unit: Some("percent"), + description: None, + href: "/properties/humidity", + }, + led: Property { + ty: Type::Boolean, + unit: None, + description: Some("A red LED"), + href: "/properties/led", + }, }, + ty: Type::Thing, }, - ty: Type::Thing, - }) + 852 + )) ) } } diff --git a/src/lib.rs b/src/lib.rs index a56b4435c..1f21e9852 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,7 +74,7 @@ pub mod ser; #[doc(inline)] pub use self::de::{from_slice, from_str}; #[doc(inline)] -pub use self::ser::{to_string, to_vec}; +pub use self::ser::{to_slice, to_string, to_vec}; #[allow(deprecated)] unsafe fn uninitialized() -> T { diff --git a/src/ser/map.rs b/src/ser/map.rs index dd1bfde79..8e010c75a 100644 --- a/src/ser/map.rs +++ b/src/ser/map.rs @@ -1,35 +1,24 @@ use serde::ser; -use heapless::ArrayLength; - use crate::ser::{Error, Result, Serializer}; -pub struct SerializeMap<'a, B> -where - B: ArrayLength, -{ - ser: &'a mut Serializer, +pub struct SerializeMap<'a, 'b> { + ser: &'a mut Serializer<'b>, first: bool, } -impl<'a, B> SerializeMap<'a, B> -where - B: ArrayLength, -{ - pub(crate) fn new(ser: &'a mut Serializer) -> Self { +impl<'a, 'b: 'a> SerializeMap<'a, 'b> { + pub(crate) fn new(ser: &'a mut Serializer<'b>) -> Self { SerializeMap { ser, first: true } } } -impl<'a, B> ser::SerializeMap for SerializeMap<'a, B> -where - B: ArrayLength, -{ +impl<'a, 'b: 'a> ser::SerializeMap for SerializeMap<'a, 'b> { type Ok = (); type Error = Error; fn end(self) -> Result { - self.ser.buf.push(b'}')?; + self.ser.push(b'}')?; Ok(()) } @@ -38,11 +27,11 @@ where T: ser::Serialize, { if !self.first { - self.ser.buf.push(b',')?; + self.ser.push(b',')?; } self.first = false; key.serialize(&mut *self.ser)?; - self.ser.buf.extend_from_slice(b":")?; + self.ser.extend_from_slice(b":")?; Ok(()) } diff --git a/src/ser/mod.rs b/src/ser/mod.rs index e9d862b83..c19138b06 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -51,19 +51,43 @@ impl fmt::Display for Error { } } -pub(crate) struct Serializer -where - B: heapless::ArrayLength, -{ - buf: Vec, +pub(crate) struct Serializer<'a> { + buf: &'a mut [u8], + current_length: usize, } -impl Serializer -where - B: heapless::ArrayLength, -{ - fn new() -> Self { - Serializer { buf: Vec::new() } +impl<'a> Serializer<'a> { + fn new(buf: &'a mut [u8]) -> Self { + Serializer { + buf, + current_length: 0, + } + } + + fn push(&mut self, c: u8) -> Result<()> { + if self.current_length < self.buf.len() { + unsafe { self.push_unchecked(c) }; + Ok(()) + } else { + Err(Error::BufferFull) + } + } + + unsafe fn push_unchecked(&mut self, c: u8) { + self.buf[self.current_length] = c; + self.current_length += 1; + } + + fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> { + if self.current_length + other.len() > self.buf.len() { + // won't fit in the buf; don't modify anything and return an error + Err(Error::BufferFull) + } else { + for c in other { + unsafe { self.push_unchecked(c.clone()) }; + } + Ok(()) + } } } @@ -86,8 +110,7 @@ macro_rules! serialize_unsigned { } } - $self.buf.extend_from_slice(&buf[i..])?; - Ok(()) + $self.extend_from_slice(&buf[i..]) }}; } @@ -120,8 +143,7 @@ macro_rules! serialize_signed { } else { i += 1; } - $self.buf.extend_from_slice(&buf[i..])?; - Ok(()) + $self.extend_from_slice(&buf[i..]) }}; } @@ -129,8 +151,7 @@ macro_rules! serialize_fmt { ($self:ident, $uxx:ident, $fmt:expr, $v:expr) => {{ let mut s: String<$uxx> = String::new(); write!(&mut s, $fmt, $v).unwrap(); - $self.buf.extend_from_slice(s.as_bytes())?; - Ok(()) + $self.extend_from_slice(s.as_bytes()) }}; } @@ -148,28 +169,23 @@ fn hex(c: u8) -> (u8, u8) { (hex_4bit(c >> 4), hex_4bit(c & 0x0F)) } -impl<'a, B> ser::Serializer for &'a mut Serializer -where - B: heapless::ArrayLength, -{ +impl<'a, 'b: 'a> ser::Serializer for &'a mut Serializer<'b> { type Ok = (); type Error = Error; - type SerializeSeq = SerializeSeq<'a, B>; - type SerializeTuple = SerializeSeq<'a, B>; + type SerializeSeq = SerializeSeq<'a, 'b>; + type SerializeTuple = SerializeSeq<'a, 'b>; type SerializeTupleStruct = Unreachable; type SerializeTupleVariant = Unreachable; - type SerializeMap = SerializeMap<'a, B>; - type SerializeStruct = SerializeStruct<'a, B>; + type SerializeMap = SerializeMap<'a, 'b>; + type SerializeStruct = SerializeStruct<'a, 'b>; type SerializeStructVariant = Unreachable; fn serialize_bool(self, v: bool) -> Result { if v { - self.buf.extend_from_slice(b"true")?; + self.extend_from_slice(b"true") } else { - self.buf.extend_from_slice(b"false")?; + self.extend_from_slice(b"false") } - - Ok(()) } fn serialize_i8(self, v: i8) -> Result { @@ -225,8 +241,7 @@ where } fn serialize_str(self, v: &str) -> Result { - self.buf.push(b'"')?; - + self.push(b'"')?; // Do escaping according to "6. MUST represent all strings (including object member names) in // their minimal-length UTF-8 encoding": https://gibson042.github.io/canonicaljson-spec/ @@ -243,51 +258,50 @@ where for c in v.chars() { match c { '\\' => { - self.buf.push(b'\\')?; - self.buf.push(b'\\')?; + self.push(b'\\')?; + self.push(b'\\')?; } '"' => { - self.buf.push(b'\\')?; - self.buf.push(b'"')?; + self.push(b'\\')?; + self.push(b'"')?; } '\u{0008}' => { - self.buf.push(b'\\')?; - self.buf.push(b'b')?; + self.push(b'\\')?; + self.push(b'b')?; } '\u{0009}' => { - self.buf.push(b'\\')?; - self.buf.push(b't')?; + self.push(b'\\')?; + self.push(b't')?; } '\u{000A}' => { - self.buf.push(b'\\')?; - self.buf.push(b'n')?; + self.push(b'\\')?; + self.push(b'n')?; } '\u{000C}' => { - self.buf.push(b'\\')?; - self.buf.push(b'f')?; + self.push(b'\\')?; + self.push(b'f')?; } '\u{000D}' => { - self.buf.push(b'\\')?; - self.buf.push(b'r')?; + self.push(b'\\')?; + self.push(b'r')?; } '\u{0000}'..='\u{001F}' => { - self.buf.push(b'\\')?; - self.buf.push(b'u')?; - self.buf.push(b'0')?; - self.buf.push(b'0')?; + self.push(b'\\')?; + self.push(b'u')?; + self.push(b'0')?; + self.push(b'0')?; let (hex1, hex2) = hex(c as u8); - self.buf.push(hex1)?; - self.buf.push(hex2)?; + self.push(hex1)?; + self.push(hex2)?; } _ => { let encoded = c.encode_utf8(&mut encoding_tmp as &mut [u8]); - self.buf.extend_from_slice(encoded.as_bytes())?; + self.extend_from_slice(encoded.as_bytes())?; } } } - self.buf.push(b'"')?; - Ok(()) + self.push(b'"') } fn serialize_bytes(self, _v: &[u8]) -> Result { @@ -295,8 +309,7 @@ where } fn serialize_none(self) -> Result { - self.buf.extend_from_slice(b"null")?; - Ok(()) + self.extend_from_slice(b"null") } fn serialize_some(self, value: &T) -> Result @@ -348,7 +361,7 @@ where } fn serialize_seq(self, _len: Option) -> Result { - self.buf.push(b'[')?; + self.push(b'[')?; Ok(SerializeSeq::new(self)) } @@ -376,13 +389,13 @@ where } fn serialize_map(self, _len: Option) -> Result { - self.buf.push(b'{')?; + self.push(b'{')?; Ok(SerializeMap::new(self)) } fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { - self.buf.push(b'{')?; + self.push(b'{')?; Ok(SerializeStruct::new(self)) } @@ -411,9 +424,7 @@ where B: heapless::ArrayLength, T: ser::Serialize + ?Sized, { - let mut ser = Serializer::new(); - value.serialize(&mut ser)?; - Ok(unsafe { String::from_utf8_unchecked(ser.buf) }) + Ok(unsafe { String::from_utf8_unchecked(to_vec(value)?) }) } /// Serializes the given data structure as a JSON byte vector @@ -422,9 +433,21 @@ where B: heapless::ArrayLength, T: ser::Serialize + ?Sized, { - let mut ser = Serializer::new(); + let mut buf = Vec::::new(); + buf.resize_default(B::to_usize())?; + let len = to_slice(value, &mut buf)?; + buf.truncate(len); + Ok(buf) +} + +/// Serializes the given data structure as a JSON byte vector into the provided buffer +pub fn to_slice(value: &T, buf: &mut [u8]) -> Result +where + T: ser::Serialize + ?Sized, +{ + let mut ser = Serializer::new(buf); value.serialize(&mut ser)?; - Ok(ser.buf) + Ok(ser.current_length) } impl ser::Error for Error { @@ -513,11 +536,20 @@ mod tests { #[test] fn array() { + let buf = &mut [0u8; 128]; + let len = crate::to_slice(&[0, 1, 2], buf).unwrap(); + assert_eq!(len, 7); + assert_eq!(&buf[..len], b"[0,1,2]"); assert_eq!(&*crate::to_string::(&[0, 1, 2]).unwrap(), "[0,1,2]"); } #[test] fn bool() { + let buf = &mut [0u8; 128]; + let len = crate::to_slice(&true, buf).unwrap(); + assert_eq!(len, 4); + assert_eq!(&buf[..len], b"true"); + assert_eq!(&*crate::to_string::(&true).unwrap(), "true"); } @@ -555,23 +587,62 @@ mod tests { assert_eq!(&*crate::to_string::("💣").unwrap(), r#""💣""#); // 4 byte character // " and \ must be escaped - assert_eq!(&*crate::to_string::("foo\"bar").unwrap(), r#""foo\"bar""#); - assert_eq!(&*crate::to_string::("foo\\bar").unwrap(), r#""foo\\bar""#); + assert_eq!( + &*crate::to_string::("foo\"bar").unwrap(), + r#""foo\"bar""# + ); + assert_eq!( + &*crate::to_string::("foo\\bar").unwrap(), + r#""foo\\bar""# + ); // \b, \t, \n, \f, \r must be escaped in their two-character escaping - assert_eq!(&*crate::to_string::(" \u{0008} ").unwrap(), r#"" \b ""#); - assert_eq!(&*crate::to_string::(" \u{0009} ").unwrap(), r#"" \t ""#); - assert_eq!(&*crate::to_string::(" \u{000A} ").unwrap(), r#"" \n ""#); - assert_eq!(&*crate::to_string::(" \u{000C} ").unwrap(), r#"" \f ""#); - assert_eq!(&*crate::to_string::(" \u{000D} ").unwrap(), r#"" \r ""#); + assert_eq!( + &*crate::to_string::(" \u{0008} ").unwrap(), + r#"" \b ""# + ); + assert_eq!( + &*crate::to_string::(" \u{0009} ").unwrap(), + r#"" \t ""# + ); + assert_eq!( + &*crate::to_string::(" \u{000A} ").unwrap(), + r#"" \n ""# + ); + assert_eq!( + &*crate::to_string::(" \u{000C} ").unwrap(), + r#"" \f ""# + ); + assert_eq!( + &*crate::to_string::(" \u{000D} ").unwrap(), + r#"" \r ""# + ); // U+0000 through U+001F is escaped using six-character \u00xx uppercase hexadecimal escape sequences - assert_eq!(&*crate::to_string::(" \u{0000} ").unwrap(), r#"" \u0000 ""#); - assert_eq!(&*crate::to_string::(" \u{0001} ").unwrap(), r#"" \u0001 ""#); - assert_eq!(&*crate::to_string::(" \u{0007} ").unwrap(), r#"" \u0007 ""#); - assert_eq!(&*crate::to_string::(" \u{000e} ").unwrap(), r#"" \u000E ""#); - assert_eq!(&*crate::to_string::(" \u{001D} ").unwrap(), r#"" \u001D ""#); - assert_eq!(&*crate::to_string::(" \u{001f} ").unwrap(), r#"" \u001F ""#); + assert_eq!( + &*crate::to_string::(" \u{0000} ").unwrap(), + r#"" \u0000 ""# + ); + assert_eq!( + &*crate::to_string::(" \u{0001} ").unwrap(), + r#"" \u0001 ""# + ); + assert_eq!( + &*crate::to_string::(" \u{0007} ").unwrap(), + r#"" \u0007 ""# + ); + assert_eq!( + &*crate::to_string::(" \u{000e} ").unwrap(), + r#"" \u000E ""# + ); + assert_eq!( + &*crate::to_string::(" \u{001D} ").unwrap(), + r#"" \u001D ""# + ); + assert_eq!( + &*crate::to_string::(" \u{001f} ").unwrap(), + r#"" \u001F ""# + ); } #[test] diff --git a/src/ser/seq.rs b/src/ser/seq.rs index d260edddf..74fe63ecc 100644 --- a/src/ser/seq.rs +++ b/src/ser/seq.rs @@ -1,30 +1,19 @@ use serde::ser; -use heapless::ArrayLength; - use crate::ser::{Error, Result, Serializer}; -pub struct SerializeSeq<'a, B> -where - B: ArrayLength, -{ - de: &'a mut Serializer, +pub struct SerializeSeq<'a, 'b> { + de: &'a mut Serializer<'b>, first: bool, } -impl<'a, B> SerializeSeq<'a, B> -where - B: ArrayLength, -{ - pub(crate) fn new(de: &'a mut Serializer) -> Self { +impl<'a, 'b: 'a> SerializeSeq<'a, 'b> { + pub(crate) fn new(de: &'a mut Serializer<'b>) -> Self { SerializeSeq { de, first: true } } } -impl<'a, B> ser::SerializeSeq for SerializeSeq<'a, B> -where - B: ArrayLength, -{ +impl<'a, 'b: 'a> ser::SerializeSeq for SerializeSeq<'a, 'b> { type Ok = (); type Error = Error; @@ -33,7 +22,7 @@ where T: ser::Serialize, { if !self.first { - self.de.buf.push(b',')?; + self.de.push(b',')?; } self.first = false; @@ -42,15 +31,12 @@ where } fn end(self) -> Result { - self.de.buf.push(b']')?; + self.de.push(b']')?; Ok(()) } } -impl<'a, B> ser::SerializeTuple for SerializeSeq<'a, B> -where - B: ArrayLength, -{ +impl<'a, 'b: 'a> ser::SerializeTuple for SerializeSeq<'a, 'b> { type Ok = (); type Error = Error; diff --git a/src/ser/struct_.rs b/src/ser/struct_.rs index b76826766..71558f667 100644 --- a/src/ser/struct_.rs +++ b/src/ser/struct_.rs @@ -1,30 +1,19 @@ use serde::ser; -use heapless::ArrayLength; - use crate::ser::{Error, Result, Serializer}; -pub struct SerializeStruct<'a, B> -where - B: ArrayLength, -{ - ser: &'a mut Serializer, +pub struct SerializeStruct<'a, 'b> { + ser: &'a mut Serializer<'b>, first: bool, } -impl<'a, B> SerializeStruct<'a, B> -where - B: ArrayLength, -{ - pub(crate) fn new(ser: &'a mut Serializer) -> Self { +impl<'a, 'b: 'a> SerializeStruct<'a, 'b> { + pub(crate) fn new(ser: &'a mut Serializer<'b>) -> Self { SerializeStruct { ser, first: true } } } -impl<'a, B> ser::SerializeStruct for SerializeStruct<'a, B> -where - B: ArrayLength, -{ +impl<'a, 'b: 'a> ser::SerializeStruct for SerializeStruct<'a, 'b> { type Ok = (); type Error = Error; @@ -34,13 +23,13 @@ where { // XXX if `value` is `None` we not produce any output for this field if !self.first { - self.ser.buf.push(b',')?; + self.ser.push(b',')?; } self.first = false; - self.ser.buf.push(b'"')?; - self.ser.buf.extend_from_slice(key.as_bytes())?; - self.ser.buf.extend_from_slice(b"\":")?; + self.ser.push(b'"')?; + self.ser.extend_from_slice(key.as_bytes())?; + self.ser.extend_from_slice(b"\":")?; value.serialize(&mut *self.ser)?; @@ -48,7 +37,7 @@ where } fn end(self) -> Result { - self.ser.buf.push(b'}')?; + self.ser.push(b'}')?; Ok(()) } }