diff --git a/src/de.rs b/src/de.rs index 7f0c857..22fd693 100644 --- a/src/de.rs +++ b/src/de.rs @@ -114,6 +114,7 @@ impl<'de: 'a, 'a, R: io::Read> de::Deserializer<'de> for &'a mut Decoder { match tag { 0x0a => visitor.visit_map(MapDecoder::new(self)), + 0x00 => visitor.visit_map(MapDecoder::new_seeded(self, 0x00)), _ => Err(Error::NoRootCompound), } } @@ -137,6 +138,10 @@ where fn new(outer: &'a mut Decoder) -> Self { MapDecoder { outer, tag: None } } + + fn new_seeded(outer: &'a mut Decoder, seed: u8) -> Self { + MapDecoder { outer, tag: Some(seed) } + } } impl<'de: 'a, 'a, R: io::Read + 'a> de::MapAccess<'de> for MapDecoder<'a, R> { @@ -146,6 +151,11 @@ impl<'de: 'a, 'a, R: io::Read + 'a> de::MapAccess<'de> for MapDecoder<'a, R> { where K: de::DeserializeSeed<'de>, { + if matches!(self.tag, Some(0x00)) { + // we exit early here - we know that the map contains nothing from a 0x00 headed object + return Ok(None); + } + let tag = raw::read_bare_byte(&mut self.outer.reader)?; // NBT indicates the end of a compound type with a 0x00 tag. diff --git a/src/ser.rs b/src/ser.rs index fe8c0f0..ff7803a 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -269,7 +269,12 @@ where /// Serialize maps as `Tag_Compound` data. #[inline] - fn serialize_map(self, _len: Option) -> Result { + fn serialize_map(self, len: Option) -> Result { + if matches!(len, Some(0)) { + self.write_header(0, None)?; + return Ok(Compound::from_outer(self)); + } + let header = self.header; // Circumvent strange borrowing errors. self.write_header(0x0a, header)?; Ok(Compound::from_outer(self)) @@ -277,7 +282,12 @@ where /// Serialize structs as `Tag_Compound` data. #[inline] - fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + fn serialize_struct(self, _name: &'static str, len: usize) -> Result { + if len == 0 { + self.write_header(0, None)?; + return Ok(Compound::from_outer(self)); + } + let header = self.header; // Circumvent strange borrowing errors. self.write_header(0x0a, header)?; Ok(Compound::from_outer(self))