From f90876a324da9bfbd6224959808991b3f583c013 Mon Sep 17 00:00:00 2001 From: Faerbit Date: Tue, 6 Aug 2024 21:54:16 +0200 Subject: [PATCH] [bencode/ser] Implement structs --- src/bencode/ser.rs | 78 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/src/bencode/ser.rs b/src/bencode/ser.rs index 2cc1b83..0e205ab 100644 --- a/src/bencode/ser.rs +++ b/src/bencode/ser.rs @@ -51,7 +51,7 @@ impl<'a> ser::Serializer for &'a mut Serializer type SerializeTupleStruct = Self; type SerializeTupleVariant = Self; type SerializeMap = MapSerializer<'a>; - type SerializeStruct = Self; + type SerializeStruct = MapSerializer<'a>; type SerializeStructVariant = Self; fn serialize_bool(self, v: bool) -> Result<()> { @@ -196,8 +196,14 @@ impl<'a> ser::Serializer for &'a mut Serializer }) } - fn serialize_struct(self, name: &'static str, len: usize) -> Result { - todo!() + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + self.output.push('d' as u8); + Ok(MapSerializer{ + super_serializer: self, + sorted_map: BTreeMap::new(), + last_inserted_key: Vec::new(), + value_serializer: Serializer::new(), + }) } fn serialize_struct_variant(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize) -> Result { @@ -270,6 +276,16 @@ 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); + self.super_serializer.output.extend(value); + } + self.super_serializer.output.push('e' as u8); + } +} + impl <'a> ser::SerializeMap for MapSerializer<'a> { type Ok = (); type Error = Error; @@ -313,16 +329,12 @@ impl <'a> ser::SerializeMap for MapSerializer<'a> { } fn end(self) -> Result<()> { - for (key, value) in self.sorted_map.into_iter() { - self.super_serializer.output.extend(key); - self.super_serializer.output.extend(value); - } - self.super_serializer.output.push('e' as u8); + self.finalize(); Ok(()) } } -impl <'a> ser::SerializeStruct for &'a mut Serializer { +impl <'a> ser::SerializeStruct for MapSerializer<'a> { type Ok = (); type Error = Error; @@ -330,11 +342,25 @@ impl <'a> ser::SerializeStruct for &'a mut Serializer { where T: ?Sized + Serialize { - todo!() + match value.serialize(&mut self.value_serializer) { + Ok(_) => (), + Err(e) => + return match e { + Error::OptionNone => Ok(()), + _ => Err(e), + }, + }; + let mut val_str = Vec::new(); + swap(&mut self.value_serializer.output, &mut val_str); + key.serialize(&mut self.value_serializer)?; + let mut key_str = Vec::new(); + swap(&mut self.value_serializer.output, &mut key_str); + self.sorted_map.insert(key_str, val_str); + Ok(()) } fn end(self) -> Result<()> { - self.output.push('e' as u8); + self.finalize(); Ok(()) } } @@ -358,7 +384,7 @@ impl <'a> ser::SerializeStructVariant for &'a mut Serializer { #[cfg(test)] mod test { use std::collections::HashMap; - + use serde::Serialize; use crate::bencode::ser::to_string; #[test] @@ -407,4 +433,32 @@ mod test { "d3:foo4:💩e" ); } + + #[test] + fn test_dict() { + #[derive(Serialize)] + struct A { + a: i32, + } + assert_eq!(to_string(&A{a: 23}).unwrap(), "d1:ai23ee"); + + #[derive(Serialize)] + struct B { + l: Vec, + m: HashMap, + o: Option, + o2: Option, + } + assert_eq!(to_string(&B{ + l: vec![3, 7, 9], + m: HashMap::from([ + ("foo".to_string(), 23), + ("bar".to_string(), 18), + ]), + o: Some("baz".to_string()), + o2: None, + }).unwrap(), + "d1:lli3ei7ei9ee1:md3:bari18e3:fooi23ee1:o3:baze" + ) + } }