impl Debug for UtPex

This commit is contained in:
Igor Katson 2024-08-25 13:20:13 +01:00
parent 90bfb85bcc
commit c7b7dc300f
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
3 changed files with 43 additions and 19 deletions

View file

@ -25,7 +25,7 @@ pub struct PeerExtendedMessageIds {
} }
#[derive(Debug)] #[derive(Debug)]
pub enum ExtendedMessage<ByteBuf: std::hash::Hash + Eq> { pub enum ExtendedMessage<ByteBuf: std::hash::Hash + Eq + AsRef<[u8]>> {
Handshake(ExtendedHandshake<ByteBuf>), Handshake(ExtendedHandshake<ByteBuf>),
UtMetadata(UtMetadata<ByteBuf>), UtMetadata(UtMetadata<ByteBuf>),
UtPex(UtPex<ByteBuf>), UtPex(UtPex<ByteBuf>),
@ -34,8 +34,8 @@ pub enum ExtendedMessage<ByteBuf: std::hash::Hash + Eq> {
impl<ByteBuf> CloneToOwned for ExtendedMessage<ByteBuf> impl<ByteBuf> CloneToOwned for ExtendedMessage<ByteBuf>
where where
ByteBuf: CloneToOwned + std::hash::Hash + Eq, ByteBuf: CloneToOwned + std::hash::Hash + Eq + AsRef<[u8]>,
<ByteBuf as CloneToOwned>::Target: std::hash::Hash + Eq, <ByteBuf as CloneToOwned>::Target: std::hash::Hash + Eq + AsRef<[u8]>,
{ {
type Target = ExtendedMessage<<ByteBuf as CloneToOwned>::Target>; type Target = ExtendedMessage<<ByteBuf as CloneToOwned>::Target>;
@ -53,7 +53,7 @@ where
} }
} }
impl<'a, ByteBuf: 'a + std::hash::Hash + Eq + Serialize> ExtendedMessage<ByteBuf> { impl<'a, ByteBuf: 'a + std::hash::Hash + Eq + Serialize + AsRef<[u8]>> ExtendedMessage<ByteBuf> {
pub fn serialize( pub fn serialize(
&self, &self,
out: &mut Vec<u8>, out: &mut Vec<u8>,
@ -72,27 +72,30 @@ impl<'a, ByteBuf: 'a + std::hash::Hash + Eq + Serialize> ExtendedMessage<ByteBuf
bencode_serialize_to_writer(h, out)?; bencode_serialize_to_writer(h, out)?;
} }
ExtendedMessage::UtMetadata(u) => { ExtendedMessage::UtMetadata(u) => {
let emsg_id = extended_handshake_ut_metadata().ut_metadata.ok_or_else(|| { let emsg_id = extended_handshake_ut_metadata()
anyhow::anyhow!("need peer's handshake to serialize ut_metadata") .ut_metadata
})?; .ok_or_else(|| {
anyhow::anyhow!("need peer's handshake to serialize ut_metadata")
})?;
out.push(emsg_id); out.push(emsg_id);
u.serialize(out); u.serialize(out);
}, }
ExtendedMessage::UtPex(m) => { ExtendedMessage::UtPex(m) => {
let emsg_id = extended_handshake_ut_metadata().ut_pex.ok_or_else(|| { let emsg_id = extended_handshake_ut_metadata().ut_pex.ok_or_else(|| {
anyhow::anyhow!("need peer's handshake to serialize ut_pex, or peer does't support ut_pex") anyhow::anyhow!(
"need peer's handshake to serialize ut_pex, or peer does't support ut_pex"
)
})?; })?;
out.push(emsg_id); out.push(emsg_id);
bencode_serialize_to_writer(m, out)?; bencode_serialize_to_writer(m, out)?;
}, }
} }
Ok(()) Ok(())
} }
pub fn deserialize(mut buf: &'a [u8]) -> Result<Self, MessageDeserializeError> pub fn deserialize(mut buf: &'a [u8]) -> Result<Self, MessageDeserializeError>
where where
ByteBuf: Deserialize<'a> + From<&'a [u8]>, ByteBuf: Deserialize<'a> + From<&'a [u8]> + AsRef<[u8]>,
{ {
let emsg_id = buf.first().copied().ok_or_else(|| { let emsg_id = buf.first().copied().ok_or_else(|| {
MessageDeserializeError::Other(anyhow::anyhow!( MessageDeserializeError::Other(anyhow::anyhow!(

View file

@ -12,7 +12,7 @@ pub struct PexPeerInfo {
pub addr: SocketAddr, pub addr: SocketAddr,
} }
#[derive(Debug, Serialize, Default, Deserialize)] #[derive(Serialize, Default, Deserialize)]
pub struct UtPex<B> { pub struct UtPex<B> {
added: B, added: B,
#[serde(rename = "added.f")] #[serde(rename = "added.f")]
@ -26,6 +26,27 @@ pub struct UtPex<B> {
dropped6: B, dropped6: B,
} }
impl<B> core::fmt::Debug for UtPex<B>
where
B: AsRef<[u8]>,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
struct IterDebug<I>(I);
impl<I> core::fmt::Debug for IterDebug<I>
where
I: Iterator<Item = PexPeerInfo> + Clone,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_list().entries(self.0.clone()).finish()
}
}
f.debug_struct("UtPex")
.field("added", &IterDebug(self.added_peers()))
.field("dropped", &IterDebug(self.dropped_peers()))
.finish()
}
}
impl<B> CloneToOwned for UtPex<B> impl<B> CloneToOwned for UtPex<B>
where where
B: CloneToOwned, B: CloneToOwned,
@ -52,7 +73,7 @@ where
buf: &'a B, buf: &'a B,
flags: &'a Option<B>, flags: &'a Option<B>,
ip_len: usize, ip_len: usize,
) -> impl Iterator<Item = PexPeerInfo> + 'a { ) -> impl Iterator<Item = PexPeerInfo> + Clone + 'a {
let addrs = buf.as_ref().chunks_exact(ip_len + 2).map(move |c| { let addrs = buf.as_ref().chunks_exact(ip_len + 2).map(move |c| {
let ip = match ip_len { let ip = match ip_len {
4 => IpAddr::from(TryInto::<[u8; 4]>::try_into(&c[..4]).unwrap()), 4 => IpAddr::from(TryInto::<[u8; 4]>::try_into(&c[..4]).unwrap()),
@ -74,12 +95,12 @@ where
}) })
} }
pub fn added_peers(&self) -> impl Iterator<Item = PexPeerInfo> + '_ { pub fn added_peers(&self) -> impl Iterator<Item = PexPeerInfo> + Clone + '_ {
self.added_peers_inner(&self.added, &self.added_f, 4) self.added_peers_inner(&self.added, &self.added_f, 4)
.chain(self.added_peers_inner(&self.added6, &self.added6_f, 16)) .chain(self.added_peers_inner(&self.added6, &self.added6_f, 16))
} }
pub fn dropped_peers(&self) -> impl Iterator<Item = PexPeerInfo> + '_ { pub fn dropped_peers(&self) -> impl Iterator<Item = PexPeerInfo> + Clone + '_ {
self.added_peers_inner(&self.dropped, &None, 4) self.added_peers_inner(&self.dropped, &None, 4)
.chain(self.added_peers_inner(&self.dropped6, &None, 16)) .chain(self.added_peers_inner(&self.dropped6, &None, 16))
} }

View file

@ -186,7 +186,7 @@ impl From<anyhow::Error> for MessageDeserializeError {
} }
#[derive(Debug)] #[derive(Debug)]
pub enum Message<ByteBuf: std::hash::Hash + Eq> { pub enum Message<ByteBuf: std::hash::Hash + Eq + AsRef<[u8]>> {
Request(Request), Request(Request),
Cancel(Request), Cancel(Request),
Bitfield(ByteBuf), Bitfield(ByteBuf),
@ -212,8 +212,8 @@ pub struct Bitfield<'a> {
impl<ByteBuf> CloneToOwned for Message<ByteBuf> impl<ByteBuf> CloneToOwned for Message<ByteBuf>
where where
ByteBuf: CloneToOwned + std::hash::Hash + Eq, ByteBuf: CloneToOwned + std::hash::Hash + Eq + AsRef<[u8]>,
<ByteBuf as CloneToOwned>::Target: std::hash::Hash + Eq, <ByteBuf as CloneToOwned>::Target: std::hash::Hash + Eq + AsRef<[u8]>,
{ {
type Target = Message<<ByteBuf as CloneToOwned>::Target>; type Target = Message<<ByteBuf as CloneToOwned>::Target>;