Compare commits
2 Commits
ca70aa3815
...
a731269a7d
Author | SHA1 | Date | |
---|---|---|---|
a731269a7d | |||
7475974764 |
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1069,6 +1069,7 @@ dependencies = [
|
||||
"hex-literal",
|
||||
"rand",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"sha1",
|
||||
"urlencoding",
|
||||
]
|
||||
|
@ -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"
|
||||
|
@ -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(())
|
||||
}
|
||||
|
331
src/serde_bencode.rs
Normal file
331
src/serde_bencode.rs
Normal file
@ -0,0 +1,331 @@
|
||||
use std::fmt;
|
||||
use std::fmt::Display;
|
||||
|
||||
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,
|
||||
ExpectedIntegerEnd,
|
||||
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::ExpectedIntegerEnd => formatter.write_str("expected integer end char 'e'"),
|
||||
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 next_byte(&mut self) -> Result<u8> {
|
||||
let ch = self.peek_byte()?;
|
||||
self.input = &self.input[1..];
|
||||
Ok(ch)
|
||||
}
|
||||
|
||||
fn parse_int<T>(&mut self) -> Result<T>
|
||||
where
|
||||
T: From<i8> + std::str::FromStr,
|
||||
{
|
||||
if self.next_byte()? != 'i' as u8 {
|
||||
return Err(Error::Syntax)
|
||||
}
|
||||
let end_pos = self.input.iter().position(|&x| x == 'e' as u8)
|
||||
.ok_or_else(|| Error::ExpectedIntegerEnd)?;
|
||||
let int_str = std::str::from_utf8(&self.input[..end_pos]).map_err(|_| Error::Syntax)?;
|
||||
let int = int_str.parse::<T>().map_err(|_| Error::ExpectedInteger)?;
|
||||
self.input = &self.input[end_pos + 1..];
|
||||
Ok(int)
|
||||
}
|
||||
}
|
||||
|
||||
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::{Error, from_bytes};
|
||||
|
||||
#[test]
|
||||
fn test_int() {
|
||||
assert_eq!(from_bytes(&"i42e".as_bytes()), Ok(42));
|
||||
assert_eq!(from_bytes::<i32>(&"i42".as_bytes()), Err(Error::ExpectedIntegerEnd));
|
||||
assert_eq!(from_bytes::<i32>(&"42e".as_bytes()), Err(Error::Syntax));
|
||||
// 2**16 + 1 = 65537
|
||||
assert_eq!(from_bytes(&"i65537e".as_bytes()), Ok(65537));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user