[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,
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"),
}
}
}

View File

@ -132,14 +132,14 @@ impl<'a> ser::Serializer for &'a mut Serializer
}
fn serialize_none(self) -> Result<()> {
todo!()
Err(Error::OptionNone)
}
fn serialize_some<T>(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"
);
}
}