[bencode/ser] Implement structs
This commit is contained in:
parent
b085afe9d7
commit
f90876a324
@ -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<Self::SerializeStruct> {
|
||||
todo!()
|
||||
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
|
||||
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<Self::SerializeStructVariant> {
|
||||
@ -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<i16>,
|
||||
m: HashMap<String, i32>,
|
||||
o: Option<String>,
|
||||
o2: Option<String>,
|
||||
}
|
||||
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"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user