[bencode/ser] Properly sort dictionaries

This commit is contained in:
Fabian 2024-08-12 00:40:51 +02:00
parent 40a298f3cc
commit ee092097c7

View File

@ -329,8 +329,7 @@ impl <'a> ser::SerializeTupleVariant for &'a mut Serializer {
impl<'a> MapSerializer<'a> {
fn finalize(self) {
for (key, value) in self.sorted_map.into_iter() {
self.super_serializer.output.extend(key);
for value in self.sorted_map.values() {
self.super_serializer.output.extend(value);
}
self.super_serializer.output.push('e' as u8);
@ -346,10 +345,12 @@ impl <'a> ser::SerializeMap for MapSerializer<'a> {
T: ?Sized + Serialize
{
key.serialize(&mut self.value_serializer)?;
self.last_inserted_key = self.value_serializer.output.clone();
let insert_key_start = self.value_serializer.output.iter().position(|x| *x == b':')
.ok_or(Error::Syntax("missing \":\" from just serialized byte string".to_string()))?;
self.last_inserted_key = self.value_serializer.output[insert_key_start+1..].to_vec();
let mut key_to_insert = Vec::new();
swap(&mut self.value_serializer.output, &mut key_to_insert);
self.sorted_map.insert(key_to_insert, Vec::new());
self.sorted_map.insert(self.last_inserted_key.clone(), key_to_insert);
Ok(())
}
@ -370,7 +371,7 @@ impl <'a> ser::SerializeMap for MapSerializer<'a> {
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;
x.extend(value_to_insert);
} else {
self.sorted_map.remove(&self.last_inserted_key);
self.value_serializer.output.clear();
@ -404,9 +405,13 @@ impl <'a> ser::SerializeStruct for MapSerializer<'a> {
let mut val_str = Vec::new();
swap(&mut self.value_serializer.output, &mut val_str);
key.serialize(&mut self.value_serializer)?;
let insert_key_start = self.value_serializer.output.iter().position(|x| *x == b':')
.ok_or(Error::Syntax("missing \":\" from just serialized byte string".to_string()))?;
let insert_key = self.value_serializer.output[insert_key_start+1..].to_vec();
let mut key_str = Vec::new();
swap(&mut self.value_serializer.output, &mut key_str);
self.sorted_map.insert(key_str, val_str);
key_str.extend(val_str);
self.sorted_map.insert(insert_key, key_str);
Ok(())
}
@ -467,15 +472,15 @@ mod test {
fn test_map() {
assert_eq!(to_string(&HashMap::from([
("foo", 42),
("bar", 13),
("bare", 13),
])).unwrap(),
"d3:bari13e3:fooi42ee"
"d4:barei13e3:fooi42ee"
);
assert_eq!(to_string(&HashMap::from([
("foo", "💩"),
("bar", "🙈"),
("bare", "🙈"),
])).unwrap(),
"d3:bar4:🙈3:foo4:💩e"
"d4:bare4:🙈3:foo4:💩e"
);
assert_eq!(to_string(&HashMap::from([
("foo", Some("💩")),
@ -504,12 +509,12 @@ mod test {
l: vec![3, 7, 9],
m: HashMap::from([
("foo".to_string(), 23),
("bar".to_string(), 18),
("bare".to_string(), 18),
]),
o: Some("baz".to_string()),
o2: None,
}).unwrap(),
"d1:lli3ei7ei9ee1:md3:bari18e3:fooi23ee1:o3:baze"
"d1:lli3ei7ei9ee1:md4:barei18e3:fooi23ee1:o3:baze"
);
#[derive(Serialize)]