1use std::{sync::Arc, time::Duration};
4
5use async_trait::async_trait;
6
7use crate::{PathKind, Result};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct NetBenchTelemetry {
12 pub path: PathKind,
14 pub lost_packets: u64,
16 pub lost_bytes: u64,
18 pub congestion_events: u64,
20 pub rx_datagrams: u64,
22 pub tx_datagrams: u64,
24 pub current_mtu: u16,
26 pub black_holes_detected: u64,
28 pub rtt: Duration,
30}
31
32impl Default for NetBenchTelemetry {
33 fn default() -> Self {
34 Self {
35 path: PathKind::Unknown,
36 lost_packets: 0,
37 lost_bytes: 0,
38 congestion_events: 0,
39 rx_datagrams: 0,
40 tx_datagrams: 0,
41 current_mtu: 0,
42 black_holes_detected: 0,
43 rtt: Duration::ZERO,
44 }
45 }
46}
47
48#[async_trait]
50pub trait NetBenchSendStream: Send {
51 async fn write(&mut self, bytes: &[u8]) -> Result<usize> {
53 self.write_all(bytes).await?;
54 Ok(bytes.len())
55 }
56 async fn write_all(&mut self, bytes: &[u8]) -> Result<()>;
58 fn finish(&mut self) -> Result<()>;
64 fn cancel(&mut self);
66}
67
68#[async_trait]
69impl<T: NetBenchSendStream + ?Sized> NetBenchSendStream for Box<T> {
70 async fn write(&mut self, bytes: &[u8]) -> Result<usize> {
71 (**self).write(bytes).await
72 }
73
74 async fn write_all(&mut self, bytes: &[u8]) -> Result<()> {
75 (**self).write_all(bytes).await
76 }
77
78 fn finish(&mut self) -> Result<()> {
79 (**self).finish()
80 }
81
82 fn cancel(&mut self) {
83 (**self).cancel();
84 }
85}
86
87#[async_trait]
89pub trait NetBenchReceiveStream: Send {
90 async fn read(&mut self, bytes: &mut [u8]) -> Result<usize>;
92 async fn read_exact(&mut self, bytes: &mut [u8]) -> Result<()>;
94 fn cancel(&mut self);
96}
97
98#[async_trait]
99impl<T: NetBenchReceiveStream + ?Sized> NetBenchReceiveStream for Box<T> {
100 async fn read(&mut self, bytes: &mut [u8]) -> Result<usize> {
101 (**self).read(bytes).await
102 }
103
104 async fn read_exact(&mut self, bytes: &mut [u8]) -> Result<()> {
105 (**self).read_exact(bytes).await
106 }
107
108 fn cancel(&mut self) {
109 (**self).cancel();
110 }
111}
112
113pub trait NetBenchBidirectionalStream: Send {
115 fn into_split(self: Box<Self>)
117 -> (Box<dyn NetBenchSendStream>, Box<dyn NetBenchReceiveStream>);
118}
119
120#[async_trait]
125pub trait NetBenchSession: Send + Sync {
126 fn remote_peer_id(&self) -> String;
128 fn telemetry(&self) -> NetBenchTelemetry;
130 fn max_datagram_size(&self) -> Option<usize>;
132 async fn open_bi(&self) -> Result<Box<dyn NetBenchBidirectionalStream>>;
134 async fn accept_bi(&self) -> Result<Box<dyn NetBenchBidirectionalStream>>;
136 async fn send_datagram(&self, bytes: Vec<u8>) -> Result<()>;
138 async fn read_datagram(&self) -> Result<Vec<u8>>;
140}
141
142pub struct NetBenchFlow {
144 session: Arc<dyn NetBenchSession>,
145 control_send: Box<dyn NetBenchSendStream>,
146 control_recv: Box<dyn NetBenchReceiveStream>,
147}
148
149impl std::fmt::Debug for NetBenchFlow {
150 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151 formatter
152 .debug_struct("NetBenchFlow")
153 .field("remote_peer_id", &self.session.remote_peer_id())
154 .finish_non_exhaustive()
155 }
156}
157
158impl NetBenchFlow {
159 #[must_use]
162 pub fn new(
163 session: Arc<dyn NetBenchSession>,
164 control_send: Box<dyn NetBenchSendStream>,
165 control_recv: Box<dyn NetBenchReceiveStream>,
166 ) -> Self {
167 Self {
168 session,
169 control_send,
170 control_recv,
171 }
172 }
173
174 pub(crate) fn into_parts(
175 self,
176 ) -> (
177 Arc<dyn NetBenchSession>,
178 Box<dyn NetBenchSendStream>,
179 Box<dyn NetBenchReceiveStream>,
180 ) {
181 (self.session, self.control_send, self.control_recv)
182 }
183}