use serde::{ser::SerializeMap, Serialize, Serializer};
struct AsBytes<'a>(&'a [u8]);
impl<'a> Serialize for AsBytes<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bytes(self.0)
}
}
#[derive(Debug)]
pub struct QueryMsg<'a, T> {
pub a: T,
pub q: &'a [u8],
pub t: &'a [u8],
pub v: Option<&'a [u8]>,
}
impl<'a, T> Serialize for QueryMsg<'a, T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(None)?;
map.serialize_entry("a", &self.a)?;
map.serialize_entry("q", &AsBytes(self.q))?;
map.serialize_entry("t", &AsBytes(self.t))?;
if let Some(v) = &self.v {
map.serialize_entry("v", &AsBytes(v))?;
}
map.serialize_entry("y", "q")?;
map.end()
}
}
#[derive(Debug)]
pub struct RespMsg<'a, T> {
pub r: T,
pub t: &'a [u8],
pub v: Option<&'a [u8]>,
}
impl<'a, T> Serialize for RespMsg<'a, T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(None)?;
map.serialize_entry("r", &self.r)?;
map.serialize_entry("t", &AsBytes(self.t))?;
if let Some(v) = self.v {
map.serialize_entry("v", &AsBytes(v))?;
}
map.serialize_entry("y", "r")?;
map.end()
}
}
#[derive(Debug)]
pub struct ErrMsg<'a, T> {
pub e: T,
pub t: &'a [u8],
pub v: Option<&'a [u8]>,
}
impl<'a, T> Serialize for ErrMsg<'a, T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(None)?;
map.serialize_entry("e", &self.e)?;
map.serialize_entry("t", &AsBytes(self.t))?;
if let Some(v) = self.v {
map.serialize_entry("v", &AsBytes(v))?;
}
map.serialize_entry("y", "e")?;
map.end()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::dht::krpc::{Error, ErrorCode, Msg, Ty};
#[test]
fn test_serde_error() -> Result<(), Error> {
let encoded_error = b"d1:eli201e23:A Generic Error Ocurrede1:t2:aa1:y1:ee";
let error_msg: Msg<'_> = bt_bencode::from_slice(encoded_error)?;
assert_eq!(error_msg.ty(), Ty::Error);
assert_eq!(error_msg.tx_id(), b"aa".as_ref());
assert_eq!(
error_msg.error(),
Some((ErrorCode::GenericError, "A Generic Error Ocurred"))
);
let ser_error_msg = ErrMsg {
e: &(201, "A Generic Error Ocurred"),
t: b"aa",
v: None,
};
let ser_msg = bt_bencode::to_vec(&ser_error_msg).unwrap();
assert_eq!(ser_msg, encoded_error);
Ok(())
}
}