Reimplementing bencoding with Serde. Scaffolding setup. WIP

This commit is contained in:
Fabian 2024-07-31 20:22:37 +02:00
parent ca70aa3815
commit 7475974764
4 changed files with 320 additions and 2 deletions

1
Cargo.lock generated
View File

@ -1069,6 +1069,7 @@ dependencies = [
"hex-literal",
"rand",
"reqwest",
"serde",
"sha1",
"urlencoding",
]

View File

@ -9,6 +9,7 @@ sha1 = "0.10.6"
reqwest = { version = "0.12.5", features = ["blocking"] }
rand = "0.8.5"
urlencoding = "2.1.3"
serde = "1.0.204"
[dev-dependencies]
hex-literal = "0.4.1"

View File

@ -9,6 +9,7 @@ use reqwest::Url;
use crate::bencode::{Bencode, ByteString};
mod bencode;
mod serde_bencode;
#[derive(Debug)]
struct FileInfo {
@ -217,8 +218,8 @@ fn main() -> Result<()> {
let resp = client.get(url).send()?;
let status = resp.status();
let body = resp.text()?;
println!("Response: {} {}", status, body);
// let body = resp.text()?;
println!("Response: {status}");
Ok(())
}

315
src/serde_bencode.rs Normal file
View File

@ -0,0 +1,315 @@
use std::fmt;
use std::fmt::Display;
use std::ops::{AddAssign, MulAssign};
use serde::{de, Deserialize, ser};
use serde::de::Visitor;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, PartialEq)]
pub enum Error {
Message(String),
Eof,
Syntax,
ExpectedInteger,
ExpectedListEnd,
ExpectedDictEnd,
TrailingCharacters,
}
impl ser::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Error::Message(msg.to_string())
}
}
impl de::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Error::Message(msg.to_string())
}
}
impl Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::Message(msg) => formatter.write_str(msg),
Error::Eof => formatter.write_str("unexpected end of input"),
Error::Syntax => formatter.write_str("syntax error"),
Error::ExpectedInteger => formatter.write_str("expected integer"),
Error::ExpectedListEnd => formatter.write_str("expected list end char 'e'"),
Error::ExpectedDictEnd => formatter.write_str("expected dict end char 'e'"),
Error::TrailingCharacters => formatter.write_str("trailing characters")
}
}
}
impl std::error::Error for Error {}
pub struct Deserializer<'de> {
input: &'de [u8],
}
impl<'de> Deserializer<'de> {
pub fn from_bytes(input: &'de [u8]) -> Self {
Deserializer { input }
}
}
pub fn from_bytes<'a, T>(b: &'a &[u8]) -> Result<T>
where
T: Deserialize<'a>,
{
let mut deserializer = Deserializer::from_bytes(b);
let t = T::deserialize(&mut deserializer)?;
if deserializer.input.is_empty() {
Ok(t)
} else {
Err(Error::TrailingCharacters)
}
}
impl<'de> Deserializer<'de> {
fn peek_byte(&mut self) -> Result<u8> {
if let Some(&result) = self.input.get(0) {
Ok(result)
} else {
Err(Error::Eof)
}
}
fn parse_int<T>(&mut self) -> Result<T>
where
//T: AddAssign<T> + MulAssign<T> + From<i8>,
T: From<i8>,
{
Ok(42.into())
}
}
impl <'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
todo!()
}
fn deserialize_bool<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
visitor.visit_i8(self.parse_int()?)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
visitor.visit_i16(self.parse_int()?)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
visitor.visit_i32(self.parse_int()?)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
visitor.visit_i64(self.parse_int()?)
}
fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
visitor.visit_i128(self.parse_int()?)
}
fn deserialize_u8<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_u16<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_u32<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_u64<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_f32<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_f64<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_char<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
todo!()
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
todo!()
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
todo!()
}
fn deserialize_byte_buf<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
todo!()
}
fn deserialize_option<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_unit<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_unit_struct<V>(self, _: &'static str, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
todo!()
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
todo!()
}
fn deserialize_tuple<V>(self, _: usize, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_tuple_struct<V>(self, _: &'static str, _: usize, _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
todo!()
}
fn deserialize_struct<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
{
todo!()
}
fn deserialize_enum<V>(self, _: &'static str, _: &'static [&'static str], _: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
unimplemented!()
}
fn deserialize_identifier<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
todo!()
}
fn deserialize_ignored_any<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
todo!()
}
}
#[cfg(test)]
mod test {
use crate::serde_bencode::from_bytes;
#[test]
fn test_int() {
assert_eq!(from_bytes(&"i42e".as_bytes()), Ok(42));
// 2**16 + 1 = 65537
assert_eq!(from_bytes(&"i65537e".as_bytes()), Ok(65537));
}
}