use crate::datagram::Datagram;
use crate::driver::utils::varint_w2q;
use crate::driver::Driver;
use crate::error::ConnectionError;
use crate::error::SendDatagramError;
use crate::stream::OpeningBiStream;
use crate::stream::OpeningUniStream;
use crate::stream::RecvStream;
use crate::stream::SendStream;
use std::net::SocketAddr;
use std::time::Duration;
use wtransport_proto::ids::SessionId;
use wtransport_proto::varint::VarInt;
#[derive(Debug)]
pub struct Connection {
quic_connection: quinn::Connection,
driver: Driver,
session_id: SessionId,
}
impl Connection {
pub(crate) fn new(
quic_connection: quinn::Connection,
driver: Driver,
session_id: SessionId,
) -> Self {
Self {
quic_connection,
driver,
session_id,
}
}
pub async fn accept_uni(&self) -> Result<RecvStream, ConnectionError> {
let stream = self
.driver
.accept_uni(self.session_id)
.await
.map_err(|driver_error| {
ConnectionError::with_driver_error(driver_error, &self.quic_connection)
})?
.into_stream();
Ok(RecvStream::new(stream))
}
pub async fn accept_bi(&self) -> Result<(SendStream, RecvStream), ConnectionError> {
let stream = self
.driver
.accept_bi(self.session_id)
.await
.map_err(|driver_error| {
ConnectionError::with_driver_error(driver_error, &self.quic_connection)
})?
.into_stream();
Ok((SendStream::new(stream.0), RecvStream::new(stream.1)))
}
pub async fn open_uni(&self) -> Result<OpeningUniStream, ConnectionError> {
self.driver
.open_uni(self.session_id)
.await
.map_err(|driver_error| {
ConnectionError::with_driver_error(driver_error, &self.quic_connection)
})
}
pub async fn open_bi(&self) -> Result<OpeningBiStream, ConnectionError> {
self.driver
.open_bi(self.session_id)
.await
.map_err(|driver_error| {
ConnectionError::with_driver_error(driver_error, &self.quic_connection)
})
}
pub async fn receive_datagram(&self) -> Result<Datagram, ConnectionError> {
self.driver
.receive_datagram(self.session_id)
.await
.map_err(|driver_error| {
ConnectionError::with_driver_error(driver_error, &self.quic_connection)
})
}
pub fn send_datagram<D>(&self, payload: D) -> Result<(), SendDatagramError>
where
D: AsRef<[u8]>,
{
self.driver.send_datagram(self.session_id, payload.as_ref())
}
pub fn close(&self, error_code: VarInt, reason: &[u8]) {
self.quic_connection.close(varint_w2q(error_code), reason);
}
pub async fn closed(&self) {
let _ = self.quic_connection.closed().await;
}
#[inline(always)]
pub fn session_id(&self) -> SessionId {
self.session_id
}
#[inline(always)]
pub fn remote_address(&self) -> SocketAddr {
self.quic_connection.remote_address()
}
#[inline(always)]
pub fn stable_id(&self) -> usize {
self.quic_connection.stable_id()
}
#[inline(always)]
pub fn max_datagram_size(&self) -> Option<usize> {
self.quic_connection
.max_datagram_size()
.map(|quic_max_size| quic_max_size - Datagram::header_size(self.session_id))
}
#[inline(always)]
pub fn rtt(&self) -> Duration {
self.quic_connection.rtt()
}
}