Move everything to workspaces
This commit is contained in:
parent
75547d3000
commit
ad867e8e3c
42 changed files with 338 additions and 168 deletions
195
crates/bencode/src/bencode_value.rs
Normal file
195
crates/bencode/src/bencode_value.rs
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
use std::{collections::HashMap, marker::PhantomData};
|
||||
|
||||
use buffers::{ByteBuf, ByteString};
|
||||
use clone_to_owned::CloneToOwned;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
|
||||
use crate::serde_bencode_de::from_bytes;
|
||||
|
||||
pub fn dyn_from_bytes<'de, ByteBuf>(buf: &'de [u8]) -> anyhow::Result<BencodeValue<ByteBuf>>
|
||||
where
|
||||
ByteBuf: From<&'de [u8]> + Deserialize<'de> + std::hash::Hash + Eq,
|
||||
{
|
||||
from_bytes(buf)
|
||||
}
|
||||
|
||||
impl<ByteBuf: serde::Serialize + Eq + std::hash::Hash> serde::Serialize for BencodeValue<ByteBuf> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
match self {
|
||||
BencodeValue::Bytes(b) => b.serialize(serializer),
|
||||
BencodeValue::Integer(v) => v.serialize(serializer),
|
||||
BencodeValue::List(l) => l.serialize(serializer),
|
||||
BencodeValue::Dict(d) => d.serialize(serializer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, ByteBuf> serde::de::Deserialize<'de> for BencodeValue<ByteBuf>
|
||||
where
|
||||
ByteBuf: From<&'de [u8]> + Deserialize<'de> + std::hash::Hash + Eq,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct Visitor<ByteBuf> {
|
||||
buftype: PhantomData<ByteBuf>,
|
||||
}
|
||||
|
||||
impl<'de, ByteBuf> serde::de::Visitor<'de> for Visitor<ByteBuf>
|
||||
where
|
||||
ByteBuf: From<&'de [u8]> + Deserialize<'de> + std::hash::Hash + Eq,
|
||||
{
|
||||
type Value = BencodeValue<ByteBuf>;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(formatter, "a bencode value")
|
||||
}
|
||||
|
||||
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(BencodeValue::Integer(v))
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let mut v = Vec::new();
|
||||
while let Some(value) = seq.next_element()? {
|
||||
v.push(value);
|
||||
}
|
||||
Ok(BencodeValue::List(v))
|
||||
}
|
||||
|
||||
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(BencodeValue::Bytes(ByteBuf::from(v)))
|
||||
}
|
||||
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: serde::de::MapAccess<'de>,
|
||||
{
|
||||
let mut hmap = HashMap::new();
|
||||
while let Some(key) = map.next_key()? {
|
||||
let value = map.next_value()?;
|
||||
hmap.insert(key, value);
|
||||
}
|
||||
Ok(BencodeValue::Dict(hmap))
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_any(Visitor {
|
||||
buftype: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// A dynamic value when we don't know exactly what we are deserializing.
|
||||
// Useful for debugging.
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum BencodeValue<ByteBuf: std::hash::Hash + Eq> {
|
||||
Bytes(ByteBuf),
|
||||
Integer(i64),
|
||||
List(Vec<BencodeValue<ByteBuf>>),
|
||||
Dict(HashMap<ByteBuf, BencodeValue<ByteBuf>>),
|
||||
}
|
||||
|
||||
impl<ByteBuf: std::fmt::Debug + std::hash::Hash + Eq> std::fmt::Debug for BencodeValue<ByteBuf> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
BencodeValue::Bytes(b) => std::fmt::Debug::fmt(b, f),
|
||||
BencodeValue::Integer(i) => std::fmt::Debug::fmt(i, f),
|
||||
BencodeValue::List(l) => std::fmt::Debug::fmt(l, f),
|
||||
BencodeValue::Dict(d) => std::fmt::Debug::fmt(d, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<ByteBuf> CloneToOwned for BencodeValue<ByteBuf>
|
||||
where
|
||||
ByteBuf: CloneToOwned + std::hash::Hash + Eq,
|
||||
<ByteBuf as CloneToOwned>::Target: Eq + std::hash::Hash,
|
||||
{
|
||||
type Target = BencodeValue<<ByteBuf as CloneToOwned>::Target>;
|
||||
|
||||
fn clone_to_owned(&self) -> Self::Target {
|
||||
match self {
|
||||
BencodeValue::Bytes(b) => BencodeValue::Bytes(b.clone_to_owned()),
|
||||
BencodeValue::Integer(i) => BencodeValue::Integer(*i),
|
||||
BencodeValue::List(l) => BencodeValue::List(l.clone_to_owned()),
|
||||
BencodeValue::Dict(d) => BencodeValue::Dict(d.clone_to_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type BencodeValueBorrowed<'a> = BencodeValue<ByteBuf<'a>>;
|
||||
pub type BencodeValueOwned = BencodeValue<ByteString>;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::serde_bencode_ser::bencode_serialize_to_writer;
|
||||
|
||||
use super::*;
|
||||
use serde::Serialize;
|
||||
use std::io::Read;
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_torrent_dyn() {
|
||||
let mut buf = Vec::new();
|
||||
let filename = "resources/ubuntu-21.04-desktop-amd64.iso.torrent";
|
||||
std::fs::File::open(filename)
|
||||
.unwrap()
|
||||
.read_to_end(&mut buf)
|
||||
.unwrap();
|
||||
|
||||
let torrent_borrowed: BencodeValueBorrowed = from_bytes(&buf).unwrap();
|
||||
let torrent_owned: BencodeValueOwned = from_bytes(&buf).unwrap();
|
||||
dbg!(torrent_borrowed);
|
||||
dbg!(torrent_owned);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_torrent_dyn() {
|
||||
let mut buf = Vec::new();
|
||||
let filename = "resources/ubuntu-21.04-desktop-amd64.iso.torrent";
|
||||
std::fs::File::open(filename)
|
||||
.unwrap()
|
||||
.read_to_end(&mut buf)
|
||||
.unwrap();
|
||||
|
||||
let torrent: BencodeValueBorrowed = from_bytes(&buf).unwrap();
|
||||
|
||||
let mut buf = Vec::<u8>::new();
|
||||
bencode_serialize_to_writer(&torrent, &mut buf).unwrap();
|
||||
|
||||
let new_torrent = from_bytes(&buf).unwrap();
|
||||
assert_eq!(torrent, new_torrent);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_struct_with_option() {
|
||||
#[derive(Serialize)]
|
||||
struct Test {
|
||||
f1: i64,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
missing: Option<i64>,
|
||||
}
|
||||
let test = Test {
|
||||
f1: 100,
|
||||
missing: None,
|
||||
};
|
||||
let mut buf = Vec::<u8>::new();
|
||||
bencode_serialize_to_writer(&test, &mut buf).unwrap();
|
||||
assert_eq!(&buf, b"d2:f1i100ee");
|
||||
}
|
||||
}
|
||||
7
crates/bencode/src/lib.rs
Normal file
7
crates/bencode/src/lib.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
mod bencode_value;
|
||||
mod serde_bencode_de;
|
||||
mod serde_bencode_ser;
|
||||
|
||||
pub use bencode_value::*;
|
||||
pub use serde_bencode_de::*;
|
||||
pub use serde_bencode_ser::*;
|
||||
567
crates/bencode/src/serde_bencode_de.rs
Normal file
567
crates/bencode/src/serde_bencode_de.rs
Normal file
|
|
@ -0,0 +1,567 @@
|
|||
use buffers::ByteBuf;
|
||||
use serde::de::Error as DeError;
|
||||
use sha1w::{ISha1, Sha1};
|
||||
|
||||
pub struct BencodeDeserializer<'de> {
|
||||
buf: &'de [u8],
|
||||
field_context: Vec<ByteBuf<'de>>,
|
||||
parsing_key: bool,
|
||||
|
||||
// This is a f**ing hack
|
||||
pub is_torrent_info: bool,
|
||||
pub torrent_info_digest: Option<[u8; 20]>,
|
||||
}
|
||||
|
||||
impl<'de> BencodeDeserializer<'de> {
|
||||
pub fn new_from_buf(buf: &'de [u8]) -> BencodeDeserializer<'de> {
|
||||
Self {
|
||||
buf,
|
||||
field_context: Default::default(),
|
||||
parsing_key: false,
|
||||
is_torrent_info: false,
|
||||
torrent_info_digest: None,
|
||||
}
|
||||
}
|
||||
pub fn into_remaining(self) -> &'de [u8] {
|
||||
self.buf
|
||||
}
|
||||
fn parse_integer(&mut self) -> Result<i64, Error> {
|
||||
match self.buf.iter().copied().position(|e| e == b'e') {
|
||||
Some(end) => {
|
||||
let intbytes = &self.buf[1..end];
|
||||
let value: i64 = std::str::from_utf8(intbytes)
|
||||
.map_err(|e| Error::new_from_err(e).set_context(self))?
|
||||
.parse()
|
||||
.map_err(|e| Error::new_from_err(e).set_context(self))?;
|
||||
let rem = self.buf.get(end + 1..).unwrap_or_default();
|
||||
self.buf = rem;
|
||||
Ok(value)
|
||||
}
|
||||
None => Err(Error::custom("cannot parse integer, unexpected EOF").set_context(self)),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_bytes(&mut self) -> Result<&'de [u8], Error> {
|
||||
match self.buf.iter().copied().position(|e| e == b':') {
|
||||
Some(length_delim) => {
|
||||
let lenbytes = &self.buf[..length_delim];
|
||||
let length: usize = std::str::from_utf8(lenbytes)
|
||||
.map_err(|e| Error::new_from_err(e).set_context(self))?
|
||||
.parse()
|
||||
.map_err(|e| Error::new_from_err(e).set_context(self))?;
|
||||
let bytes_start = length_delim + 1;
|
||||
let bytes_end = bytes_start + length;
|
||||
let bytes = &self.buf.get(bytes_start..bytes_end).ok_or_else(|| {
|
||||
Error::custom(format!(
|
||||
"could not get byte range {}..{}, data in the buffer: {:?}",
|
||||
bytes_start, bytes_end, &self.buf
|
||||
))
|
||||
.set_context(self)
|
||||
})?;
|
||||
let rem = self.buf.get(bytes_end..).unwrap_or_default();
|
||||
self.buf = rem;
|
||||
Ok(bytes)
|
||||
}
|
||||
None => Err(Error::custom("cannot parse bytes, unexpected EOF").set_context(self)),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_bytes_checked(&mut self) -> Result<&'de [u8], Error> {
|
||||
let first = match self.buf.first().copied() {
|
||||
Some(first) => first,
|
||||
None => return Err(Error::custom("expected bencode bytes, got EOF").set_context(self)),
|
||||
};
|
||||
match first {
|
||||
b'0'..=b'9' => {}
|
||||
_ => return Err(Error::custom("expected bencode bytes").set_context(self)),
|
||||
}
|
||||
let b = self.parse_bytes()?;
|
||||
if self.parsing_key {
|
||||
self.field_context.push(ByteBuf(b));
|
||||
}
|
||||
Ok(b)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_bytes<'a, T>(buf: &'a [u8]) -> anyhow::Result<T>
|
||||
where
|
||||
T: serde::de::Deserialize<'a>,
|
||||
{
|
||||
let mut de = BencodeDeserializer::new_from_buf(buf);
|
||||
let v = T::deserialize(&mut de)?;
|
||||
if !de.buf.is_empty() {
|
||||
anyhow::bail!(
|
||||
"deserialized successfully, but {} bytes remaining",
|
||||
de.buf.len()
|
||||
)
|
||||
}
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ErrorKind {
|
||||
Other(anyhow::Error),
|
||||
NotSupported(&'static str),
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ErrorContext {
|
||||
field_stack: Vec<String>,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ErrorContext {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut it = self.field_stack.iter();
|
||||
if let Some(field) = it.next() {
|
||||
write!(f, "\"{}\"", field)?;
|
||||
} else {
|
||||
return Ok(());
|
||||
}
|
||||
for field in self.field_stack.iter().skip(1) {
|
||||
write!(f, " -> \"{}\"", field)?;
|
||||
}
|
||||
f.write_str(": ")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Error {
|
||||
kind: ErrorKind,
|
||||
context: ErrorContext,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ErrorKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ErrorKind::Other(err) => err.fmt(f),
|
||||
ErrorKind::NotSupported(s) => write!(f, "{} is not supported by bencode", s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}{}", self.context, self.kind)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match &self.kind {
|
||||
ErrorKind::Other(err) => err.source(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error {
|
||||
fn new_from_err<E>(e: E) -> Self
|
||||
where
|
||||
E: std::error::Error + Send + Sync + 'static,
|
||||
{
|
||||
Error {
|
||||
kind: ErrorKind::Other(anyhow::Error::new(e)),
|
||||
context: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_from_kind(kind: ErrorKind) -> Self {
|
||||
Self {
|
||||
kind,
|
||||
context: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_from_anyhow(e: anyhow::Error) -> Self {
|
||||
Error {
|
||||
kind: ErrorKind::Other(e),
|
||||
context: Default::default(),
|
||||
}
|
||||
}
|
||||
fn custom_with_de<M: std::fmt::Display>(msg: M, de: &BencodeDeserializer<'_>) -> Self {
|
||||
Self::custom(msg).set_context(de)
|
||||
}
|
||||
fn set_context(mut self, de: &BencodeDeserializer<'_>) -> Self {
|
||||
self.context = ErrorContext {
|
||||
field_stack: de.field_context.iter().map(|s| format!("{}", s)).collect(),
|
||||
};
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::de::Error for Error {
|
||||
fn custom<T>(msg: T) -> Self
|
||||
where
|
||||
T: std::fmt::Display,
|
||||
{
|
||||
Self {
|
||||
kind: ErrorKind::Other(anyhow::anyhow!("{}", msg)),
|
||||
context: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut BencodeDeserializer<'de> {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
match self.buf.first().copied() {
|
||||
Some(b'd') => self.deserialize_map(visitor),
|
||||
Some(b'i') => self.deserialize_u64(visitor),
|
||||
Some(b'l') => self.deserialize_seq(visitor),
|
||||
Some(_) => self.deserialize_bytes(visitor),
|
||||
None => Err(Error::custom_with_de("empty input", self)),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_bool<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(
|
||||
Error::new_from_kind(ErrorKind::NotSupported("bencode doesn't support booleans"))
|
||||
.set_context(self),
|
||||
)
|
||||
}
|
||||
|
||||
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_i64(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_i64(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_i64(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
if !self.buf.starts_with(b"i") {
|
||||
return Err(Error::custom_with_de("expected bencode int", self));
|
||||
}
|
||||
visitor
|
||||
.visit_i64(self.parse_integer()?)
|
||||
.map_err(|e: Self::Error| e.set_context(self))
|
||||
}
|
||||
|
||||
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_i64(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_i64(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_i64(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_i64(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(
|
||||
Error::new_from_kind(ErrorKind::NotSupported("bencode doesn't support floats"))
|
||||
.set_context(self),
|
||||
)
|
||||
}
|
||||
|
||||
fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(
|
||||
Error::new_from_kind(ErrorKind::NotSupported("bencode doesn't support floats"))
|
||||
.set_context(self),
|
||||
)
|
||||
}
|
||||
|
||||
fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(
|
||||
Error::new_from_kind(ErrorKind::NotSupported("bencode doesn't support chars"))
|
||||
.set_context(self),
|
||||
)
|
||||
}
|
||||
|
||||
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let first = match self.buf.first().copied() {
|
||||
Some(first) => first,
|
||||
None => {
|
||||
return Err(Error::custom_with_de(
|
||||
"expected bencode string, got EOF",
|
||||
self,
|
||||
))
|
||||
}
|
||||
};
|
||||
match first {
|
||||
b'0'..=b'9' => {}
|
||||
_ => return Err(Error::custom_with_de("expected bencode string", self)),
|
||||
}
|
||||
let b = self.parse_bytes()?;
|
||||
let s = std::str::from_utf8(b).map_err(|e| {
|
||||
Error::new_from_anyhow(anyhow::anyhow!("error reading utf-8: {}", e)).set_context(self)
|
||||
})?;
|
||||
visitor
|
||||
.visit_borrowed_str(s)
|
||||
.map_err(|e: Self::Error| e.set_context(self))
|
||||
}
|
||||
|
||||
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_str(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let b = self.parse_bytes_checked()?;
|
||||
visitor
|
||||
.visit_borrowed_bytes(b)
|
||||
.map_err(|e: Self::Error| e.set_context(self))
|
||||
}
|
||||
|
||||
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_bytes(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor
|
||||
.visit_some(&mut *self)
|
||||
.map_err(|e: Self::Error| e.set_context(self))
|
||||
}
|
||||
|
||||
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(Error::new_from_kind(ErrorKind::NotSupported(
|
||||
"bencode doesn't support unit types",
|
||||
))
|
||||
.set_context(self))
|
||||
}
|
||||
|
||||
fn deserialize_unit_struct<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(Error::new_from_kind(ErrorKind::NotSupported(
|
||||
"bencode doesn't support unit structs",
|
||||
))
|
||||
.set_context(self))
|
||||
}
|
||||
|
||||
fn deserialize_newtype_struct<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(
|
||||
Error::new_from_kind(ErrorKind::NotSupported("bencode doesn't newtype structs"))
|
||||
.set_context(self),
|
||||
)
|
||||
}
|
||||
|
||||
fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
if !self.buf.starts_with(b"l") {
|
||||
return Err(Error::custom(format!(
|
||||
"expected bencode list, but got {}",
|
||||
self.buf[0] as char,
|
||||
)));
|
||||
}
|
||||
self.buf = self.buf.get(1..).unwrap_or_default();
|
||||
visitor
|
||||
.visit_seq(SeqAccess { de: &mut self })
|
||||
.map_err(|e: Self::Error| e.set_context(self))
|
||||
}
|
||||
|
||||
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_seq(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_tuple_struct<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_seq(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_map<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
if !self.buf.starts_with(b"d") {
|
||||
return Err(Error::custom("expected bencode dict"));
|
||||
}
|
||||
self.buf = self.buf.get(1..).unwrap_or_default();
|
||||
visitor
|
||||
.visit_map(MapAccess { de: &mut self })
|
||||
.map_err(|e: Self::Error| e.set_context(self))
|
||||
}
|
||||
|
||||
fn deserialize_struct<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_fields: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_map(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_enum<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variants: &'static [&'static str],
|
||||
_visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(
|
||||
Error::new_from_kind(ErrorKind::NotSupported("deserializing enums not supported"))
|
||||
.set_context(self),
|
||||
)
|
||||
}
|
||||
|
||||
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let name = self.parse_bytes_checked()?;
|
||||
visitor
|
||||
.visit_borrowed_bytes(name)
|
||||
.map_err(|e: Self::Error| e.set_context(self))
|
||||
}
|
||||
|
||||
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_any(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
struct MapAccess<'a, 'de> {
|
||||
de: &'a mut BencodeDeserializer<'de>,
|
||||
}
|
||||
|
||||
struct SeqAccess<'a, 'de> {
|
||||
de: &'a mut BencodeDeserializer<'de>,
|
||||
}
|
||||
|
||||
impl<'a, 'de> serde::de::MapAccess<'de> for MapAccess<'a, 'de> {
|
||||
type Error = Error;
|
||||
|
||||
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
|
||||
where
|
||||
K: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
if self.de.buf.starts_with(b"e") {
|
||||
self.de.buf = self.de.buf.get(1..).unwrap_or_default();
|
||||
return Ok(None);
|
||||
}
|
||||
self.de.parsing_key = true;
|
||||
let retval = seed.deserialize(&mut *self.de)?;
|
||||
self.de.parsing_key = false;
|
||||
Ok(Some(retval))
|
||||
}
|
||||
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
let buf_before = self.de.buf;
|
||||
let value = seed.deserialize(&mut *self.de)?;
|
||||
if self.de.is_torrent_info && self.de.field_context.as_slice() == [ByteBuf(b"info")] {
|
||||
let len = self.de.buf.as_ptr() as usize - buf_before.as_ptr() as usize;
|
||||
let mut hash = Sha1::new();
|
||||
hash.update(&buf_before[..len]);
|
||||
let digest = hash.finish();
|
||||
self.de.torrent_info_digest = Some(digest)
|
||||
}
|
||||
self.de.field_context.pop();
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'de> serde::de::SeqAccess<'de> for SeqAccess<'a, 'de> {
|
||||
type Error = Error;
|
||||
|
||||
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
||||
where
|
||||
T: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
if self.de.buf.starts_with(b"e") {
|
||||
self.de.buf = self.de.buf.get(1..).unwrap_or_default();
|
||||
return Ok(None);
|
||||
}
|
||||
Ok(Some(seed.deserialize(&mut *self.de)?))
|
||||
}
|
||||
}
|
||||
491
crates/bencode/src/serde_bencode_ser.rs
Normal file
491
crates/bencode/src/serde_bencode_ser.rs
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use buffers::ByteString;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SerErrorKind {
|
||||
Other(anyhow::Error),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for SerErrorKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
SerErrorKind::Other(e) => write!(f, "{}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SerError {
|
||||
kind: SerErrorKind,
|
||||
}
|
||||
|
||||
impl SerError {
|
||||
fn custom_with_ser<T: std::fmt::Display, W: std::io::Write>(
|
||||
msg: T,
|
||||
_ser: &BencodeSerializer<W>,
|
||||
) -> Self {
|
||||
serde::ser::Error::custom(msg)
|
||||
}
|
||||
fn from_err_with_ser<E: std::error::Error + Send + Sync + 'static, W: std::io::Write>(
|
||||
err: E,
|
||||
_ser: &BencodeSerializer<W>,
|
||||
) -> Self {
|
||||
Self {
|
||||
kind: SerErrorKind::Other(err.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::ser::Error for SerError {
|
||||
fn custom<T>(msg: T) -> Self
|
||||
where
|
||||
T: std::fmt::Display,
|
||||
{
|
||||
Self {
|
||||
kind: SerErrorKind::Other(anyhow::anyhow!("{}", msg)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for SerError {}
|
||||
|
||||
impl std::fmt::Display for SerError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.kind)
|
||||
}
|
||||
}
|
||||
|
||||
struct BencodeSerializer<W: std::io::Write> {
|
||||
writer: W,
|
||||
hack_no_bytestring_prefix: bool,
|
||||
}
|
||||
|
||||
impl<W: std::io::Write> BencodeSerializer<W> {
|
||||
pub fn new(writer: W) -> Self {
|
||||
Self {
|
||||
writer,
|
||||
hack_no_bytestring_prefix: false,
|
||||
}
|
||||
}
|
||||
fn write_raw(&mut self, buf: &[u8]) -> Result<(), SerError> {
|
||||
self.writer
|
||||
.write_all(buf)
|
||||
.map_err(|e| SerError::from_err_with_ser(e, &self))
|
||||
}
|
||||
fn write_fmt(&mut self, fmt: core::fmt::Arguments<'_>) -> Result<(), SerError> {
|
||||
self.writer
|
||||
.write_fmt(fmt)
|
||||
.map_err(|e| SerError::from_err_with_ser(e, &self))
|
||||
}
|
||||
fn write_byte(&mut self, byte: u8) -> Result<(), SerError> {
|
||||
self.write_raw(&[byte])
|
||||
}
|
||||
fn write_number<N: std::fmt::Display>(&mut self, number: N) -> Result<(), SerError> {
|
||||
self.write_fmt(format_args!("i{}e", number))
|
||||
}
|
||||
fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerError> {
|
||||
if !self.hack_no_bytestring_prefix {
|
||||
self.write_fmt(format_args!("{}:", bytes.len()))?;
|
||||
}
|
||||
self.write_raw(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
struct SerializeSeq<'ser, W: std::io::Write> {
|
||||
ser: &'ser mut BencodeSerializer<W>,
|
||||
}
|
||||
impl<'ser, W: std::io::Write> serde::ser::SerializeSeq for SerializeSeq<'ser, W> {
|
||||
type Ok = ();
|
||||
|
||||
type Error = SerError;
|
||||
|
||||
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
value.serialize(&mut *self.ser)
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
self.ser.write_byte(b'e')
|
||||
}
|
||||
}
|
||||
|
||||
struct SerializeTuple<'ser, W: std::io::Write> {
|
||||
ser: &'ser mut BencodeSerializer<W>,
|
||||
}
|
||||
impl<'ser, W: std::io::Write> serde::ser::SerializeTuple for SerializeTuple<'ser, W> {
|
||||
type Ok = ();
|
||||
|
||||
type Error = SerError;
|
||||
|
||||
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
value.serialize(&mut *self.ser)
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
self.ser.write_byte(b'e')
|
||||
}
|
||||
}
|
||||
|
||||
struct SerializeTupleStruct<'ser, W: std::io::Write> {
|
||||
_ser: &'ser mut BencodeSerializer<W>,
|
||||
}
|
||||
impl<'ser, W: std::io::Write> serde::ser::SerializeTupleStruct for SerializeTupleStruct<'ser, W> {
|
||||
type Ok = ();
|
||||
|
||||
type Error = SerError;
|
||||
|
||||
fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
struct SerializeTupleVariant<'ser, W: std::io::Write> {
|
||||
_ser: &'ser mut BencodeSerializer<W>,
|
||||
}
|
||||
impl<'ser, W: std::io::Write> serde::ser::SerializeTupleVariant for SerializeTupleVariant<'ser, W> {
|
||||
type Ok = ();
|
||||
|
||||
type Error = SerError;
|
||||
|
||||
fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
struct SerializeMap<'ser, W: std::io::Write> {
|
||||
ser: &'ser mut BencodeSerializer<W>,
|
||||
tmp: BTreeMap<ByteString, ByteString>,
|
||||
last_key: Option<ByteString>,
|
||||
}
|
||||
impl<'ser, W: std::io::Write> serde::ser::SerializeMap for SerializeMap<'ser, W> {
|
||||
type Ok = ();
|
||||
|
||||
type Error = SerError;
|
||||
|
||||
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
let mut buf = Vec::new();
|
||||
let mut ser = BencodeSerializer::new(&mut buf);
|
||||
ser.hack_no_bytestring_prefix = true;
|
||||
key.serialize(&mut ser)?;
|
||||
self.last_key.replace(ByteString::from(buf));
|
||||
Ok(())
|
||||
// key.serialize(&mut *self.ser);
|
||||
}
|
||||
|
||||
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
let mut buf = Vec::new();
|
||||
let mut ser = BencodeSerializer::new(&mut buf);
|
||||
value.serialize(&mut ser)?;
|
||||
self.tmp
|
||||
.insert(self.last_key.take().unwrap(), ByteString::from(buf));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
for (key, value) in self.tmp {
|
||||
self.ser.write_bytes(&key)?;
|
||||
self.ser.write_raw(&value)?;
|
||||
}
|
||||
self.ser.write_byte(b'e')
|
||||
}
|
||||
}
|
||||
|
||||
struct SerializeStruct<'ser, W: std::io::Write> {
|
||||
ser: &'ser mut BencodeSerializer<W>,
|
||||
tmp: BTreeMap<&'static str, ByteString>,
|
||||
}
|
||||
impl<'ser, W: std::io::Write> serde::ser::SerializeStruct for SerializeStruct<'ser, W> {
|
||||
type Ok = ();
|
||||
|
||||
type Error = SerError;
|
||||
|
||||
fn serialize_field<T: ?Sized>(
|
||||
&mut self,
|
||||
key: &'static str,
|
||||
value: &T,
|
||||
) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
let mut buf = Vec::new();
|
||||
let mut ser = BencodeSerializer::new(&mut buf);
|
||||
value.serialize(&mut ser)?;
|
||||
self.tmp.insert(key, ByteString::from(buf));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
for (key, value) in self.tmp {
|
||||
self.ser.write_bytes(key.as_bytes())?;
|
||||
self.ser.write_raw(&value)?;
|
||||
}
|
||||
self.ser.write_byte(b'e')
|
||||
}
|
||||
}
|
||||
|
||||
struct SerializeStructVariant<'ser, W: std::io::Write> {
|
||||
_ser: &'ser mut BencodeSerializer<W>,
|
||||
}
|
||||
impl<'ser, W: std::io::Write> serde::ser::SerializeStructVariant
|
||||
for SerializeStructVariant<'ser, W>
|
||||
{
|
||||
type Ok = ();
|
||||
|
||||
type Error = SerError;
|
||||
|
||||
fn serialize_field<T: ?Sized>(
|
||||
&mut self,
|
||||
_key: &'static str,
|
||||
_value: &T,
|
||||
) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ser, W: std::io::Write> Serializer for &'ser mut BencodeSerializer<W> {
|
||||
type Ok = ();
|
||||
|
||||
type Error = SerError;
|
||||
|
||||
type SerializeSeq = SerializeSeq<'ser, W>;
|
||||
|
||||
type SerializeTuple = SerializeTuple<'ser, W>;
|
||||
|
||||
type SerializeTupleStruct = SerializeTupleStruct<'ser, W>;
|
||||
|
||||
type SerializeTupleVariant = SerializeTupleVariant<'ser, W>;
|
||||
|
||||
type SerializeMap = SerializeMap<'ser, W>;
|
||||
|
||||
type SerializeStruct = SerializeStruct<'ser, W>;
|
||||
|
||||
type SerializeStructVariant = SerializeStructVariant<'ser, W>;
|
||||
|
||||
fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
|
||||
Err(SerError::custom_with_ser(
|
||||
"bencode doesn't support booleans",
|
||||
&self,
|
||||
))
|
||||
}
|
||||
|
||||
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
|
||||
self.write_number(v)
|
||||
}
|
||||
|
||||
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
|
||||
self.write_number(v)
|
||||
}
|
||||
|
||||
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
|
||||
self.write_number(v)
|
||||
}
|
||||
|
||||
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
|
||||
self.write_number(v)
|
||||
}
|
||||
|
||||
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
|
||||
self.write_number(v)
|
||||
}
|
||||
|
||||
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
|
||||
self.write_number(v)
|
||||
}
|
||||
|
||||
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
|
||||
self.write_number(v)
|
||||
}
|
||||
|
||||
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
|
||||
self.write_number(v)
|
||||
}
|
||||
|
||||
fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
|
||||
Err(SerError::custom_with_ser(
|
||||
"bencode doesn't support f32",
|
||||
&self,
|
||||
))
|
||||
}
|
||||
|
||||
fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
|
||||
Err(SerError::custom_with_ser(
|
||||
"bencode doesn't support f32",
|
||||
&self,
|
||||
))
|
||||
}
|
||||
|
||||
fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> {
|
||||
Err(SerError::custom_with_ser(
|
||||
"bencode doesn't support chars",
|
||||
&self,
|
||||
))
|
||||
}
|
||||
|
||||
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
|
||||
self.write_bytes(v.as_bytes())
|
||||
}
|
||||
|
||||
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
|
||||
self.write_bytes(v)
|
||||
}
|
||||
|
||||
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
|
||||
Err(SerError::custom_with_ser(
|
||||
"bencode doesn't support None",
|
||||
&self,
|
||||
))
|
||||
}
|
||||
|
||||
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
||||
Err(SerError::custom_with_ser(
|
||||
"bencode doesn't support Rust unit ()",
|
||||
&self,
|
||||
))
|
||||
}
|
||||
|
||||
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn serialize_unit_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
) -> Result<Self::Ok, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn serialize_newtype_struct<T: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_value: &T,
|
||||
) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn serialize_newtype_variant<T: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_value: &T,
|
||||
) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
|
||||
self.write_byte(b'l')?;
|
||||
Ok(SerializeSeq { ser: self })
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeTupleStruct, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn serialize_tuple_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeTupleVariant, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
||||
self.write_byte(b'd')?;
|
||||
Ok(SerializeMap {
|
||||
ser: self,
|
||||
tmp: Default::default(),
|
||||
last_key: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn serialize_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStruct, Self::Error> {
|
||||
self.write_byte(b'd')?;
|
||||
Ok(SerializeStruct {
|
||||
ser: self,
|
||||
tmp: Default::default(),
|
||||
})
|
||||
}
|
||||
|
||||
fn serialize_struct_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStructVariant, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bencode_serialize_to_writer<T: Serialize, W: std::io::Write>(
|
||||
value: T,
|
||||
writer: &mut W,
|
||||
) -> Result<(), SerError> {
|
||||
let mut serializer = BencodeSerializer::new(writer);
|
||||
value.serialize(&mut serializer)?;
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue