Compare commits
2 Commits
876fbe15dc
...
7556471090
Author | SHA1 | Date | |
---|---|---|---|
7556471090 | |||
18c7eb9e81 |
@ -2,3 +2,47 @@ pub mod custom;
|
||||
pub mod de;
|
||||
pub mod ser;
|
||||
pub mod error;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::collections::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::bencode::de::from_bytes;
|
||||
use crate::bencode::ser::to_bytes;
|
||||
|
||||
#[test]
|
||||
fn test_roundtrip() {
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
struct A {
|
||||
l: Vec<String>,
|
||||
li: Vec<i32>,
|
||||
m: HashMap<String, String>,
|
||||
b: Vec<[u8; 4]>
|
||||
}
|
||||
|
||||
let a = A {
|
||||
l: vec!["foo".to_string(), "bar".to_string(), "".to_string(), "💩".to_string()],
|
||||
li: vec![18, 7, 26, 8, 9],
|
||||
m: HashMap::from([
|
||||
("foo".to_string(), "bar".to_string()),
|
||||
("💩".to_string(), "🤷♂️".to_string()),
|
||||
("18".to_string(), "asdf".to_string())
|
||||
]),
|
||||
b: vec![
|
||||
[4, 26, 7, 18],
|
||||
[24, 13, 12, 4],
|
||||
[8, 9, 10, 11]
|
||||
],
|
||||
};
|
||||
|
||||
let ser = to_bytes(&a).unwrap();
|
||||
|
||||
let de = from_bytes(&ser).unwrap();
|
||||
|
||||
assert_eq!(a, de);
|
||||
|
||||
let ser2 = to_bytes(&de).unwrap();
|
||||
|
||||
assert_eq!(ser, ser2)
|
||||
}
|
||||
}
|
||||
|
@ -4,14 +4,39 @@ use serde::{ser, Serialize};
|
||||
|
||||
use crate::bencode::error::{Error, Result};
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum TupleState {
|
||||
None,
|
||||
Unknown,
|
||||
List,
|
||||
ByteString,
|
||||
}
|
||||
|
||||
pub struct Serializer {
|
||||
output: Vec<u8>,
|
||||
tuple_state: TupleState,
|
||||
tuple_len: usize,
|
||||
}
|
||||
|
||||
impl Serializer {
|
||||
fn new() -> Self {
|
||||
Serializer {
|
||||
output: Vec::new(),
|
||||
tuple_state: TupleState::None,
|
||||
tuple_len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn write_tuple_start_bytes(&mut self) {
|
||||
if self.tuple_state == TupleState::Unknown {
|
||||
self.tuple_state = TupleState::ByteString;
|
||||
self.output.extend(format!("{}:", self.tuple_len).into_bytes());
|
||||
}
|
||||
}
|
||||
fn write_tuple_start_list(&mut self) {
|
||||
if self.tuple_state == TupleState::Unknown {
|
||||
self.tuple_state = TupleState::List;
|
||||
self.output.push('l' as u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,37 +79,47 @@ impl<'a> ser::Serializer for &'a mut Serializer
|
||||
type SerializeStruct = MapSerializer<'a>;
|
||||
type SerializeStructVariant = Self;
|
||||
|
||||
fn serialize_bool(self, v: bool) -> Result<()> {
|
||||
fn serialize_bool(self, _v: bool) -> Result<()> {
|
||||
Err(Error::WontImplement)
|
||||
}
|
||||
|
||||
fn serialize_i8(self, v: i8) -> Result<()> {
|
||||
self.write_tuple_start_list();
|
||||
self.output.extend(format!("i{v}e").into_bytes());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_i16(self, v: i16) -> Result<()> {
|
||||
self.write_tuple_start_list();
|
||||
self.output.extend(format!("i{v}e").into_bytes());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_i32(self, v: i32) -> Result<()> {
|
||||
self.write_tuple_start_list();
|
||||
self.output.extend(format!("i{v}e").into_bytes());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_i64(self, v: i64) -> Result<()> {
|
||||
self.write_tuple_start_list();
|
||||
self.output.extend(format!("i{v}e").into_bytes());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_i128(self, v: i128) -> Result<()> {
|
||||
self.write_tuple_start_list();
|
||||
self.output.extend(format!("i{v}e").into_bytes());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_u8(self, v: u8) -> Result<()> {
|
||||
todo!()
|
||||
if self.tuple_state == TupleState::None {
|
||||
return Err(Error::WontImplement);
|
||||
}
|
||||
self.write_tuple_start_bytes();
|
||||
self.output.push(v);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_u16(self, _v: u16) -> Result<()> {
|
||||
@ -112,6 +147,7 @@ impl<'a> ser::Serializer for &'a mut Serializer
|
||||
}
|
||||
|
||||
fn serialize_char(self, v: char) -> Result<()> {
|
||||
self.write_tuple_start_list();
|
||||
self.output.extend(format!("{}:", v.len_utf8()).into_bytes());
|
||||
let mut b = [0; 4];
|
||||
v.encode_utf8(&mut b);
|
||||
@ -120,12 +156,14 @@ impl<'a> ser::Serializer for &'a mut Serializer
|
||||
}
|
||||
|
||||
fn serialize_str(self, v: &str) -> Result<()> {
|
||||
self.write_tuple_start_list();
|
||||
self.output.extend(format!("{}:", v.len()).into_bytes());
|
||||
self.output.extend(v.as_bytes());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_bytes(self, v: &[u8]) -> Result<()> {
|
||||
self.write_tuple_start_list();
|
||||
self.output.extend(format!("{}:", v.len()).into_bytes());
|
||||
self.output.extend(v);
|
||||
Ok(())
|
||||
@ -139,6 +177,7 @@ impl<'a> ser::Serializer for &'a mut Serializer
|
||||
where
|
||||
T: ?Sized + Serialize
|
||||
{
|
||||
self.write_tuple_start_list();
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
@ -158,10 +197,11 @@ impl<'a> ser::Serializer for &'a mut Serializer
|
||||
where
|
||||
T: ?Sized + Serialize
|
||||
{
|
||||
self.write_tuple_start_list();
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_newtype_variant<T>(self, name: &'static str, variant_index: u32, variant: &'static str, value: &T) -> Result<()>
|
||||
fn serialize_newtype_variant<T>(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T) -> Result<()>
|
||||
where
|
||||
T: ?Sized + Serialize
|
||||
{
|
||||
@ -169,13 +209,18 @@ impl<'a> ser::Serializer for &'a mut Serializer
|
||||
}
|
||||
|
||||
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
|
||||
self.write_tuple_start_list();
|
||||
self.output.push('l' as u8);
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
|
||||
println!("tuple");
|
||||
todo!()
|
||||
if self.tuple_state != TupleState::None {
|
||||
return Err(Error::WontImplement)
|
||||
}
|
||||
self.tuple_state = TupleState::Unknown;
|
||||
self.tuple_len = len;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct> {
|
||||
@ -187,6 +232,7 @@ impl<'a> ser::Serializer for &'a mut Serializer
|
||||
}
|
||||
|
||||
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
|
||||
self.write_tuple_start_list();
|
||||
self.output.push('d' as u8);
|
||||
Ok(MapSerializer{
|
||||
super_serializer: self,
|
||||
@ -197,6 +243,7 @@ impl<'a> ser::Serializer for &'a mut Serializer
|
||||
}
|
||||
|
||||
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
|
||||
self.write_tuple_start_list();
|
||||
self.output.push('d' as u8);
|
||||
Ok(MapSerializer{
|
||||
super_serializer: self,
|
||||
@ -236,11 +283,15 @@ impl <'a> ser::SerializeTuple for &'a mut Serializer {
|
||||
where
|
||||
T: ?Sized + Serialize
|
||||
{
|
||||
todo!()
|
||||
value.serialize(&mut **self)
|
||||
}
|
||||
|
||||
fn end(self) -> Result<()> {
|
||||
todo!()
|
||||
if self.tuple_state == TupleState::List {
|
||||
self.output.push('e' as u8);
|
||||
}
|
||||
self.tuple_state = TupleState::None;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,7 +436,7 @@ impl <'a> ser::SerializeStructVariant for &'a mut Serializer {
|
||||
mod test {
|
||||
use std::collections::HashMap;
|
||||
use serde::Serialize;
|
||||
use crate::bencode::ser::to_string;
|
||||
use crate::bencode::ser::{to_bytes, to_string};
|
||||
|
||||
#[test]
|
||||
fn test_int() {
|
||||
@ -435,7 +486,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dict() {
|
||||
fn test_struct() {
|
||||
#[derive(Serialize)]
|
||||
struct A {
|
||||
a: i32,
|
||||
@ -459,6 +510,26 @@ mod test {
|
||||
o2: None,
|
||||
}).unwrap(),
|
||||
"d1:lli3ei7ei9ee1:md3:bari18e3:fooi23ee1:o3:baze"
|
||||
)
|
||||
);
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct C {
|
||||
d: HashMap<String, [u8; 3]>
|
||||
}
|
||||
|
||||
let mut expected = "d1:dd3:bar3:".as_bytes().to_vec();
|
||||
expected.extend(vec![12, 18, 9]);
|
||||
expected.extend("3:foo3:".as_bytes());
|
||||
expected.extend(vec![1, 2, 3]);
|
||||
expected.extend("ee".as_bytes());
|
||||
|
||||
assert_eq!(to_bytes(&C{
|
||||
d: HashMap::from([
|
||||
("foo".to_string(), [1, 2, 3]),
|
||||
("bar".to_string(), [12, 18, 9]),
|
||||
])
|
||||
}).unwrap(),
|
||||
expected
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user