[bencode/ser] Implement serializing Options in maps

This commit is contained in:
Fabian 2024-08-06 21:17:05 +02:00
parent f0fac02251
commit b085afe9d7
2 changed files with 29 additions and 9 deletions

View File

@ -20,6 +20,7 @@ pub enum Error {
ExpectedListEnd, ExpectedListEnd,
ExpectedDict, ExpectedDict,
ExpectedDictEnd, ExpectedDictEnd,
OptionNone,
TrailingCharacters, TrailingCharacters,
} }
@ -58,7 +59,8 @@ impl Display for Error {
Error::ExpectedListEnd => formatter.write_str("expected list end char 'e'"), Error::ExpectedListEnd => formatter.write_str("expected list end char 'e'"),
Error::ExpectedDict => formatter.write_str("expected dict start char 'd'"), Error::ExpectedDict => formatter.write_str("expected dict start char 'd'"),
Error::ExpectedDictEnd => formatter.write_str("expected dict end char 'e'"), 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"),
} }
} }
} }

View File

@ -132,14 +132,14 @@ impl<'a> ser::Serializer for &'a mut Serializer
} }
fn serialize_none(self) -> Result<()> { fn serialize_none(self) -> Result<()> {
todo!() Err(Error::OptionNone)
} }
fn serialize_some<T>(self, value: &T) -> Result<()> fn serialize_some<T>(self, value: &T) -> Result<()>
where where
T: ?Sized + Serialize T: ?Sized + Serialize
{ {
todo!() value.serialize(self)
} }
fn serialize_unit(self) -> Result<()> { fn serialize_unit(self) -> Result<()> {
@ -290,12 +290,24 @@ impl <'a> ser::SerializeMap for MapSerializer<'a> {
where where
T: ?Sized + Serialize T: ?Sized + Serialize
{ {
value.serialize(&mut self.value_serializer)?; let value_none = match value.serialize(&mut self.value_serializer) {
let mut value_to_insert = Vec::new(); Ok(_) => false,
swap(&mut self.value_serializer.output, &mut value_to_insert); Err(e) =>
let Some(x) = self.sorted_map.get_mut(&self.last_inserted_key) match e {
else { unreachable!() }; Error::OptionNone => true,
*x = value_to_insert; _ => 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(); self.last_inserted_key.clear();
Ok(()) Ok(())
} }
@ -388,5 +400,11 @@ mod test {
])).unwrap(), ])).unwrap(),
"d3:bar4:🙈3:foo4:💩e" "d3:bar4:🙈3:foo4:💩e"
); );
assert_eq!(to_string(&HashMap::from([
("foo", Some("💩")),
("bar", None),
])).unwrap(),
"d3:foo4:💩e"
);
} }
} }