http3_datagram/
datagram_handler.rs1use std::{error::Error, fmt::Display, future::poll_fn, marker::PhantomData, sync::Arc};
5
6use bytes::Buf;
7use http3::{
8 ConnectionState, SharedState,
9 error::{ConnectionError, StreamError, connection_error_creators::CloseStream},
10 quic::{self, StreamId},
11};
12
13use crate::{
14 datagram::Datagram,
15 quic_traits::{DatagramConnectionExt, RecvDatagram, SendDatagram, SendDatagramErrorIncoming},
16};
17
18#[derive(Debug)]
20pub struct DatagramSender<H: SendDatagram<B>, B: Buf> {
21 pub(crate) handler: H,
22 pub(crate) _marker: PhantomData<B>,
23 pub(crate) shared_state: Arc<SharedState>,
24 pub(crate) stream_id: StreamId,
25}
26
27impl<H, B> ConnectionState for DatagramSender<H, B>
28where
29 H: SendDatagram<B>,
30 B: Buf,
31{
32 fn shared_state(&self) -> &SharedState {
33 self.shared_state.as_ref()
34 }
35}
36
37impl<H, B> DatagramSender<H, B>
38where
39 H: SendDatagram<B>,
40 B: Buf,
41{
42 pub fn send_datagram(&mut self, data: B) -> Result<(), SendDatagramError> {
44 let encoded_datagram = Datagram::new(self.stream_id, data);
45 match self.handler.send_datagram(encoded_datagram.encode()) {
46 Ok(()) => Ok(()),
47 Err(e) => Err(self.handle_send_datagram_error(e)),
48 }
49 }
50
51 fn handle_send_datagram_error(
52 &mut self,
53 error: SendDatagramErrorIncoming,
54 ) -> SendDatagramError {
55 match error {
56 SendDatagramErrorIncoming::NotAvailable => SendDatagramError::NotAvailable,
57 SendDatagramErrorIncoming::TooLarge => SendDatagramError::TooLarge,
58 SendDatagramErrorIncoming::ConnectionError(error) => {
59 self.set_conn_error_and_wake(error.clone());
60 SendDatagramError::ConnectionError(ConnectionError::Remote(error))
61 }
62 }
63 }
64}
65
66#[derive(Debug)]
67pub struct DatagramReader<H: RecvDatagram> {
68 pub(crate) handler: H,
69 pub(crate) shared_state: Arc<SharedState>,
70}
71
72impl<H> ConnectionState for DatagramReader<H>
73where
74 H: RecvDatagram,
75{
76 fn shared_state(&self) -> &SharedState {
77 self.shared_state.as_ref()
78 }
79}
80
81impl<H> CloseStream for DatagramReader<H> where H: RecvDatagram {}
82
83impl<H> DatagramReader<H>
84where
85 H: RecvDatagram,
86{
87 pub async fn read_datagram(&mut self) -> Result<Datagram<H::Buffer>, StreamError> {
89 match poll_fn(|cx| self.handler.poll_incoming_datagram(cx)).await {
90 Ok(datagram) => Datagram::decode(datagram)
91 .map_err(|err| self.handle_connection_error_on_stream(err)),
92 Err(err) => Err(self.handle_quic_stream_error(
93 quic::StreamErrorIncoming::ConnectionErrorIncoming {
94 connection_error: err,
95 },
96 )),
97 }
98 }
99}
100
101pub trait HandleDatagramsExt<C, B>: ConnectionState
102where
103 B: Buf,
104 C: quic::Connection<B> + DatagramConnectionExt<B>,
105{
106 fn get_datagram_sender(&self, stream_id: StreamId)
108 -> DatagramSender<C::SendDatagramHandler, B>;
109 fn get_datagram_reader(&self) -> DatagramReader<C::RecvDatagramHandler>;
111}
112
113#[derive(Debug)]
115#[non_exhaustive]
116pub enum SendDatagramError {
117 #[non_exhaustive]
121 NotAvailable,
122 #[non_exhaustive]
124 TooLarge,
125 #[non_exhaustive]
127 ConnectionError(ConnectionError),
128}
129
130impl Display for SendDatagramError {
131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132 match self {
133 SendDatagramError::NotAvailable => write!(f, "Datagrams are not available"),
134 SendDatagramError::TooLarge => write!(f, "Datagram is too large"),
135 SendDatagramError::ConnectionError(e) => write!(f, "Connection error: {}", e),
136 }
137 }
138}
139
140impl Error for SendDatagramError {}