[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 SerializeTupleStruct = Self;
|
||||||
type SerializeTupleVariant = Self;
|
type SerializeTupleVariant = Self;
|
||||||
type SerializeMap = MapSerializer<'a>;
|
type SerializeMap = MapSerializer<'a>;
|
||||||
type SerializeStruct = Self;
|
type SerializeStruct = MapSerializer<'a>;
|
||||||
type SerializeStructVariant = Self;
|
type SerializeStructVariant = Self;
|
||||||
|
|
||||||
fn serialize_bool(self, v: bool) -> Result<()> {
|
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> {
|
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
|
||||||
todo!()
|
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> {
|
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> {
|
impl <'a> ser::SerializeMap for MapSerializer<'a> {
|
||||||
type Ok = ();
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
@ -313,16 +329,12 @@ impl <'a> ser::SerializeMap for MapSerializer<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<()> {
|
fn end(self) -> Result<()> {
|
||||||
for (key, value) in self.sorted_map.into_iter() {
|
self.finalize();
|
||||||
self.super_serializer.output.extend(key);
|
|
||||||
self.super_serializer.output.extend(value);
|
|
||||||
}
|
|
||||||
self.super_serializer.output.push('e' as u8);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a> ser::SerializeStruct for &'a mut Serializer {
|
impl <'a> ser::SerializeStruct for MapSerializer<'a> {
|
||||||
type Ok = ();
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
@ -330,11 +342,25 @@ impl <'a> ser::SerializeStruct for &'a mut Serializer {
|
|||||||
where
|
where
|
||||||
T: ?Sized + Serialize
|
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<()> {
|
fn end(self) -> Result<()> {
|
||||||
self.output.push('e' as u8);
|
self.finalize();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -358,7 +384,7 @@ impl <'a> ser::SerializeStructVariant for &'a mut Serializer {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use serde::Serialize;
|
||||||
use crate::bencode::ser::to_string;
|
use crate::bencode::ser::to_string;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -407,4 +433,32 @@ mod test {
|
|||||||
"d3:foo4:💩e"
|
"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