Skip to main content

moq_lite/
session.rs

1use std::{future::Future, pin::Pin};
2
3use crate::Error;
4
5/// A MoQ transport session, wrapping a WebTransport connection.
6///
7/// Created via:
8/// - [`crate::Client::connect`] for clients.
9/// - [`crate::Server::accept`] for servers.
10pub struct Session {
11	session: Box<dyn SessionInner>,
12}
13
14impl Session {
15	pub(super) fn new<S: web_transport_trait::Session>(session: S) -> Self {
16		Self {
17			session: Box::new(session),
18		}
19	}
20
21	/// Close the underlying transport session.
22	pub fn close(self, err: Error) {
23		self.session.close(err.to_code(), err.to_string().as_ref());
24	}
25
26	/// Block until the transport session is closed.
27	// TODO Remove the Result the next time we make a breaking change.
28	pub async fn closed(&self) -> Result<(), Error> {
29		self.session.closed().await;
30		Err(Error::Transport)
31	}
32}
33
34impl Drop for Session {
35	fn drop(&mut self) {
36		self.session.close(Error::Cancel.to_code(), "dropped");
37	}
38}
39
40// We use a wrapper type that is dyn-compatible to remove the generic bounds from Session.
41trait SessionInner: Send + Sync {
42	fn close(&self, code: u32, reason: &str);
43	fn closed(&self) -> Pin<Box<dyn Future<Output = ()> + Send + '_>>;
44}
45
46impl<S: web_transport_trait::Session> SessionInner for S {
47	fn close(&self, code: u32, reason: &str) {
48		S::close(self, code, reason);
49	}
50
51	fn closed(&self) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
52		Box::pin(async move {
53			let _ = S::closed(self).await;
54		})
55	}
56}