diff --git a/src/bencode/error.rs b/src/bencode/error.rs index 3d1ceb6..2e74810 100644 --- a/src/bencode/error.rs +++ b/src/bencode/error.rs @@ -20,6 +20,7 @@ pub enum Error { ExpectedListEnd, ExpectedDict, ExpectedDictEnd, + OptionNone, TrailingCharacters, } @@ -58,7 +59,8 @@ impl Display for Error { Error::ExpectedListEnd => formatter.write_str("expected list end char 'e'"), Error::ExpectedDict => formatter.write_str("expected dict start char 'd'"), Error::ExpectedDictEnd => formatter.write_str("expected dict end char 'e'"), - Error::TrailingCharacters => formatter.write_str("trailing characters") + Error::OptionNone => formatter.write_str("cannot serialize standalone none values of options"), + Error::TrailingCharacters => formatter.write_str("trailing characters"), } } } diff --git a/src/bencode/ser.rs b/src/bencode/ser.rs index e71acdc..2cc1b83 100644 --- a/src/bencode/ser.rs +++ b/src/bencode/ser.rs @@ -132,14 +132,14 @@ impl<'a> ser::Serializer for &'a mut Serializer } fn serialize_none(self) -> Result<()> { - todo!() + Err(Error::OptionNone) } fn serialize_some(self, value: &T) -> Result<()> where T: ?Sized + Serialize { - todo!() + value.serialize(self) } fn serialize_unit(self) -> Result<()> { @@ -290,12 +290,24 @@ impl <'a> ser::SerializeMap for MapSerializer<'a> { where T: ?Sized + Serialize { - value.serialize(&mut self.value_serializer)?; - let mut value_to_insert = Vec::new(); - swap(&mut self.value_serializer.output, &mut value_to_insert); - let Some(x) = self.sorted_map.get_mut(&self.last_inserted_key) - else { unreachable!() }; - *x = value_to_insert; + let value_none = match value.serialize(&mut self.value_serializer) { + Ok(_) => false, + Err(e) => + match e { + Error::OptionNone => true, + _ => return Err(e), + }, + }; + if !value_none { + let mut value_to_insert = Vec::new(); + swap(&mut self.value_serializer.output, &mut value_to_insert); + let Some(x) = self.sorted_map.get_mut(&self.last_inserted_key) + else { unreachable!() }; + *x = value_to_insert; + } else { + self.sorted_map.remove(&self.last_inserted_key); + self.value_serializer.output.clear(); + } self.last_inserted_key.clear(); Ok(()) } @@ -388,5 +400,11 @@ mod test { ])).unwrap(), "d3:bar4:🙈3:foo4:💩e" ); + assert_eq!(to_string(&HashMap::from([ + ("foo", Some("💩")), + ("bar", None), + ])).unwrap(), + "d3:foo4:💩e" + ); } }