Reimplementing bencoding with Serde. Scaffolding setup. WIP
This commit is contained in:
parent
ca70aa3815
commit
7475974764
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1069,6 +1069,7 @@ dependencies = [
|
|||||||
"hex-literal",
|
"hex-literal",
|
||||||
"rand",
|
"rand",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"serde",
|
||||||
"sha1",
|
"sha1",
|
||||||
"urlencoding",
|
"urlencoding",
|
||||||
]
|
]
|
||||||
|
@ -9,6 +9,7 @@ sha1 = "0.10.6"
|
|||||||
reqwest = { version = "0.12.5", features = ["blocking"] }
|
reqwest = { version = "0.12.5", features = ["blocking"] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
urlencoding = "2.1.3"
|
urlencoding = "2.1.3"
|
||||||
|
serde = "1.0.204"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex-literal = "0.4.1"
|
hex-literal = "0.4.1"
|
||||||
|
@ -9,6 +9,7 @@ use reqwest::Url;
|
|||||||
use crate::bencode::{Bencode, ByteString};
|
use crate::bencode::{Bencode, ByteString};
|
||||||
|
|
||||||
mod bencode;
|
mod bencode;
|
||||||
|
mod serde_bencode;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct FileInfo {
|
struct FileInfo {
|
||||||
@ -217,8 +218,8 @@ fn main() -> Result<()> {
|
|||||||
let resp = client.get(url).send()?;
|
let resp = client.get(url).send()?;
|
||||||
let status = resp.status();
|
let status = resp.status();
|
||||||
|
|
||||||
let body = resp.text()?;
|
// let body = resp.text()?;
|
||||||
println!("Response: {} {}", status, body);
|
println!("Response: {status}");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
315
src/serde_bencode.rs
Normal file
315
src/serde_bencode.rs
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user