Compare commits

..

2 Commits

Author SHA1 Message Date
7556471090 [bencode] Implement round trip test 2024-08-11 20:16:13 +02:00
18c7eb9e81 [bencode/de] Implement tuples 2024-08-11 18:58:23 +02:00
2 changed files with 126 additions and 11 deletions

View File

@ -1,4 +1,48 @@
pub mod custom;
pub mod de;
pub mod ser;
pub mod error;
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)
}
}

View File

@ -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
);
}
}