diff --git a/Cargo.lock b/Cargo.lock index 81bd925..ee74bbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "lowlevel-types" -version = "1.0.0" +version = "1.1.0" dependencies = [ "serde", "serde_test", @@ -119,11 +119,22 @@ dependencies = [ [[package]] name = "serde-binary-adv" -version = "1.0.0" +version = "1.1.0" dependencies = [ "lowlevel-types", "num", "serde", + "serde_bytes", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 41da31d..395b42b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ include = [ default-members = ["./", "lowlevel-types"] [workspace.package] -version = "1.0.0" +version = "1.1.0" edition = "2024" repository = "https://github.com/JEleniel/serde_binary_adv" license = "MIT OR Apache-2.0" @@ -39,6 +39,7 @@ unsafe_code = "forbid" lowlevel-types = { workspace = true } num = "0.4.3" serde = { workspace = true } +serde_bytes = "0.11.19" [features] default = ["streaming"] diff --git a/src/serde_binary_adv.rs b/src/serde_binary_adv.rs index 3f23343..3e12b84 100644 --- a/src/serde_binary_adv.rs +++ b/src/serde_binary_adv.rs @@ -132,6 +132,34 @@ mod tests { impl_test_x!(test_byte_array, [0x41 as u8, 0x42 as u8, 0x43 as u8]); impl_test_x!(test_array, [0x41, 0x42, 0x43]); + #[test] + fn test_borrowed_bytes() { + // The data must live as long as the deserialized reference. + let value: &[u8] = &[0x41, 0x42, 0x43]; + let serialized = Serializer::to_bytes(&value, false).unwrap(); + + // Make the test function generic over the lifetime. + fn roundtrip<'de>(input: &'de [u8]) { + let deserialized: &'de [u8] = Deserializer::from_bytes(&input, false).unwrap(); + assert_eq!(&input[1..], deserialized); + } + + roundtrip(&serialized); + } + + #[test] + fn test_serde_bytes_bytes() { + use serde_bytes::Bytes; + let data = [0x41, 0x42, 0x43]; + let value: &Bytes = Bytes::new(&data); + + let serialized = Serializer::to_bytes(&value, false).unwrap(); + let deserialized: &Bytes = + Deserializer::from_bytes(Bytes::new(&serialized), false).unwrap(); + + assert_eq!(value, deserialized); + } + #[test] fn test_map() { let mut v: HashMap = HashMap::new(); @@ -143,6 +171,15 @@ mod tests { impl_test_x!(test_tuple, ('a', 16, 0x41 as u8)); + #[test] + fn test_serde_bytes_bytebuf() { + use serde_bytes::ByteBuf; + let value = ByteBuf::from(vec![0x41, 0x42, 0x43]); + let serialized = Serializer::to_bytes(&value, false).unwrap(); + let deserialized: ByteBuf = Deserializer::from_bytes(&serialized, false).unwrap(); + assert_eq!(value, deserialized); + } + fn test(value: T) where T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + PartialEq, diff --git a/src/serde_binary_adv/de.rs b/src/serde_binary_adv/de.rs index f6ee4f6..33c34e7 100644 --- a/src/serde_binary_adv/de.rs +++ b/src/serde_binary_adv/de.rs @@ -259,7 +259,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { let len = self.next_usize()?; let bytes = self.take(len)?; - visitor.visit_bytes(bytes) + visitor.visit_borrowed_bytes(bytes) } fn deserialize_byte_buf(self, visitor: V) -> Result diff --git a/src/serde_binary_adv/ser.rs b/src/serde_binary_adv/ser.rs index d18611a..be165cb 100644 --- a/src/serde_binary_adv/ser.rs +++ b/src/serde_binary_adv/ser.rs @@ -130,8 +130,12 @@ impl<'a> ser::Serializer for &'a mut Serializer { self.serialize_vec(v.as_bytes().to_vec()) } - fn serialize_bytes(self, _v: &[u8]) -> Result { - unimplemented!() + fn serialize_bytes(self, v: &[u8]) -> Result { + if v.len() > 0 { + v.serialize(&mut *self) + } else { + self.serialize_usize(v.len()) + } } fn serialize_none(self) -> Result { diff --git a/src/serde_binary_adv/stream.rs b/src/serde_binary_adv/stream.rs index cc9e023..766d139 100644 --- a/src/serde_binary_adv/stream.rs +++ b/src/serde_binary_adv/stream.rs @@ -160,6 +160,54 @@ mod tests { assert_eq!(v, deserialized2); } + #[test] + fn test_borrowed_bytes() { + let bytes: &[u8] = &[0x41, 0x42, 0x43, 0x44]; + let mut buf = [0u8; 16]; + let mut written = &mut buf[..]; + Serializer::write_bytes(&mut written, &bytes, false).unwrap(); + let used = 16 - written.len(); + let mut read = &buf[..used]; + let deserialized: &[u8] = Deserializer::read_bytes(&mut read, false).unwrap(); + assert_eq!(bytes, deserialized); + + let mut buf2 = [0u8; 16]; + let mut written2 = &mut buf2[..]; + Serializer::write_bytes(&mut written2, &bytes, true).unwrap(); + let used2 = 16 - written2.len(); + let mut read2 = &buf2[..used2]; + let deserialized2: &[u8] = Deserializer::read_bytes(&mut read2, true).unwrap(); + assert_eq!(bytes, deserialized2); + } + + #[test] + fn test_serialize_byte_buf() { + let bytes = vec![0x41, 0x42, 0x43, 0x44]; + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &bytes, false).unwrap(); + let deserialized: Vec = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(bytes, deserialized); + + let mut buf2 = Vec::new(); + Serializer::write_bytes(&mut buf2, &bytes, true).unwrap(); + let deserialized2: Vec = Deserializer::read_bytes(&mut buf2.as_slice(), true).unwrap(); + assert_eq!(bytes, deserialized2); + } + + #[test] + fn test_deserialize_byte_buf() { + let orig = vec![0x41, 0x42, 0x43, 0x44]; + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &orig, false).unwrap(); + let deserialized: Vec = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(orig, deserialized); + + let mut buf2 = Vec::new(); + Serializer::write_bytes(&mut buf2, &orig, true).unwrap(); + let deserialized2: Vec = Deserializer::read_bytes(&mut buf2.as_slice(), true).unwrap(); + assert_eq!(orig, deserialized2); + } + #[test] fn test_map() { let mut v: HashMap = HashMap::new(); @@ -180,4 +228,194 @@ mod tests { // Test Serde Tuple impl_test_x!(test_tuple, (char, i32, u8), ('a', 16, 0x41 as u8)); + + #[test] + fn test_empty_vec() { + let v: Vec = vec![]; + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: Vec = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + + let mut buf2 = Vec::new(); + Serializer::write_bytes(&mut buf2, &v, true).unwrap(); + let deserialized2: Vec = Deserializer::read_bytes(&mut buf2.as_slice(), true).unwrap(); + assert_eq!(v, deserialized2); + } + + #[test] + fn test_empty_string() { + let s = String::new(); + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &s, false).unwrap(); + let deserialized: String = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(s, deserialized); + + let mut buf2 = Vec::new(); + Serializer::write_bytes(&mut buf2, &s, true).unwrap(); + let deserialized2: String = Deserializer::read_bytes(&mut buf2.as_slice(), true).unwrap(); + assert_eq!(s, deserialized2); + } + + #[test] + fn test_empty_map() { + let v: HashMap = HashMap::new(); + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: HashMap = + Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + + let mut buf2 = Vec::new(); + Serializer::write_bytes(&mut buf2, &v, true).unwrap(); + let deserialized2: HashMap = + Deserializer::read_bytes(&mut buf2.as_slice(), true).unwrap(); + assert_eq!(v, deserialized2); + } + + #[test] + fn test_unit_struct_roundtrip() { + let v = Unit; + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: Unit = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } + + #[test] + fn test_tuple_struct_roundtrip() { + let v = TupleStruct(1, 2, 3); + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: TupleStruct = + Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } + + #[test] + fn test_struct_with_empty_string() { + let v = Test { + byte: 0, + string: String::new(), + }; + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: Test = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } + + #[test] + fn test_option_some_none() { + let v: Option = Some(42); + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: Option = + Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + + let v: Option = None; + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: Option = + Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } + + #[test] + fn test_struct_variant_empty_fields() { + #[derive(Serialize, Deserialize, Debug, PartialEq)] + enum E { + S {}, + } + let v = E::S {}; + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: E = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } + + #[test] + fn test_tuple_variant_empty() { + #[derive(Serialize, Deserialize, Debug, PartialEq)] + enum E { + T(), + } + let v = E::T(); + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: E = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } + + #[test] + fn test_enum_unit_variant() { + #[derive(Serialize, Deserialize, Debug, PartialEq)] + enum E { + U, + } + let v = E::U; + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: E = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } + + #[test] + fn test_enum_newtype_variant() { + #[derive(Serialize, Deserialize, Debug, PartialEq)] + enum E { + N(u8), + } + let v = E::N(123); + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: E = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } + + #[test] + fn test_enum_tuple_variant() { + #[derive(Serialize, Deserialize, Debug, PartialEq)] + enum E { + T(u8, u8), + } + let v = E::T(1, 2); + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: E = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } + + #[test] + fn test_enum_struct_variant() { + #[derive(Serialize, Deserialize, Debug, PartialEq)] + enum E { + S { x: u8, y: u8 }, + } + let v = E::S { x: 1, y: 2 }; + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: E = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } + + #[test] + fn test_map_non_string_key() { + let mut v: HashMap = HashMap::new(); + v.insert(1, 2); + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: HashMap = + Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } + + #[test] + fn test_array_empty() { + let v: [u8; 0] = []; + let mut buf = Vec::new(); + Serializer::write_bytes(&mut buf, &v, false).unwrap(); + let deserialized: [u8; 0] = Deserializer::read_bytes(&mut buf.as_slice(), false).unwrap(); + assert_eq!(v, deserialized); + } } diff --git a/src/serde_binary_adv/stream/de.rs b/src/serde_binary_adv/stream/de.rs index cec7d4e..8f60366 100644 --- a/src/serde_binary_adv/stream/de.rs +++ b/src/serde_binary_adv/stream/de.rs @@ -256,18 +256,23 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { self.deserialize_str(visitor) } - fn deserialize_bytes(self, _visitor: V) -> Result + fn deserialize_bytes(self, visitor: V) -> Result where V: Visitor<'de>, { - unimplemented!() + let len = self.next_usize()?; + let vec = self.take(len)?; + let bytes: &'de [u8] = Box::leak(vec.into_boxed_slice()); + visitor.visit_borrowed_bytes(bytes) } - fn deserialize_byte_buf(self, _visitor: V) -> Result + fn deserialize_byte_buf(self, visitor: V) -> Result where V: Visitor<'de>, { - unimplemented!() + let len: usize = self.next_usize()?; + let bytes = self.take(len)?; + visitor.visit_byte_buf(bytes) } fn deserialize_option(self, visitor: V) -> Result diff --git a/src/serde_binary_adv/stream/ser.rs b/src/serde_binary_adv/stream/ser.rs index 2c1beca..dee1d18 100644 --- a/src/serde_binary_adv/stream/ser.rs +++ b/src/serde_binary_adv/stream/ser.rs @@ -140,8 +140,8 @@ impl<'se> ser::Serializer for &mut Serializer<'se> { self.serialize_vec(v.as_bytes().to_vec()) } - fn serialize_bytes(self, _v: &[u8]) -> Result { - unimplemented!() + fn serialize_bytes(self, v: &[u8]) -> Result { + self.serialize_vec(v.to_vec()) } fn serialize_none(self) -> Result {