use std::{
marker::PhantomData,
sync::{Arc, atomic::AtomicUsize},
};
use bytes::{Buf, Bytes};
use super::connection::{Connection, SendRequest};
use crate::{
config::Config,
connection::ConnectionInner,
error::ConnectionError,
proto::frame::SettingId,
quic::{self},
};
pub fn builder() -> Builder {
Builder::new()
}
pub async fn new<C, O>(
conn: C,
) -> Result<(Connection<C, Bytes>, SendRequest<O, Bytes>), ConnectionError>
where
C: quic::Connection<Bytes, OpenStreams = O>,
O: quic::OpenStreams<Bytes>,
{
Builder::new().build(conn).await
}
pub struct Builder {
config: Config,
}
impl Builder {
pub(super) fn new() -> Self {
Builder {
config: Default::default(),
}
}
#[doc(hidden)]
#[cfg(test)]
pub fn send_settings(&mut self, value: bool) -> &mut Self {
self.config.send_settings = value;
self
}
pub fn max_field_section_size(&mut self, value: u64) -> &mut Self {
self.config.settings.max_field_section_size = value;
self
}
pub fn send_grease(&mut self, enabled: bool) -> &mut Self {
self.config.send_grease = enabled;
self
}
pub fn enable_datagram(&mut self, enabled: bool) -> &mut Self {
self.config.settings.enable_datagram = enabled;
self
}
pub fn enable_extended_connect(&mut self, value: bool) -> &mut Self {
self.config.settings.enable_extended_connect = value;
self
}
pub fn qpack_max_table_capacity<T: Into<Option<u64>>>(&mut self, value: T) -> &mut Self {
self.config.settings.qpack_max_table_capacity = value.into();
self
}
pub fn qpack_blocked_streams<T: Into<Option<u64>>>(&mut self, value: T) -> &mut Self {
self.config.settings.qpack_blocked_streams = value.into();
self
}
pub fn settings_order(&mut self, order: Vec<SettingId>) -> &mut Self {
self.config.settings_order = Some(order);
self
}
pub fn extra_setting(&mut self, id: SettingId, value: u64) -> &mut Self {
self.config.extra_settings.push((id, value));
self
}
pub async fn build<C, O, B>(
&mut self,
quic: C,
) -> Result<(Connection<C, B>, SendRequest<O, B>), ConnectionError>
where
C: quic::Connection<B, OpenStreams = O>,
O: quic::OpenStreams<B>,
B: Buf,
{
let open = quic.opener();
let inner = ConnectionInner::new(quic, self.config.clone()).await?;
let send_request = SendRequest {
open,
conn_state: inner.shared.clone(),
decoder: inner.qpack_decoder(),
max_field_section_size: self.config.settings.max_field_section_size,
sender_count: Arc::new(AtomicUsize::new(1)),
send_grease_frame: self.config.send_grease,
_buf: PhantomData,
};
Ok((
Connection {
inner,
sent_closing: None,
recv_closing: None,
},
send_request,
))
}
}