use std::{
pin::Pin,
task::{Context, Poll},
};
use bytes::Buf;
use futures_util::Stream;
use quinn::{TransportConfig, VarInt};
use crate::NetError;
mod h3_client_stream;
pub use h3_client_stream::{H3ClientStream, H3ClientStreamBuilder};
pub mod h3_server;
const ALPN_H3: &[u8] = b"h3";
fn transport() -> TransportConfig {
let mut transport_config = TransportConfig::default();
transport_config.datagram_receive_buffer_size(None);
transport_config.datagram_send_buffer_size(0);
transport_config.max_concurrent_bidi_streams(VarInt::from_u32(3));
transport_config.max_concurrent_uni_streams(VarInt::from_u32(4));
transport_config
}
pub struct BodyStream<T>(T);
impl<T, B> Stream for BodyStream<T>
where
T: FnMut(&mut Context<'_>) -> Poll<Result<Option<B>, h3::error::StreamError>> + Unpin,
B: Buf,
{
type Item = Result<B, NetError>;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let this = self.get_mut();
let Poll::Ready(result) = (this.0)(cx) else {
return Poll::Pending;
};
Poll::Ready(match result {
Ok(Some(buf)) => Some(Ok(buf)),
Ok(None) => None,
Err(e) => Some(Err(NetError::from(format!(
"h3 stream receive data failed: {e}"
)))),
})
}
}
impl<T, B> From<T> for BodyStream<T>
where
T: FnMut(&mut Context<'_>) -> Poll<Result<Option<B>, h3::error::StreamError>> + Unpin,
B: Buf,
{
fn from(stream: T) -> Self {
Self(stream)
}
}