1use std::{future::Future, pin::Pin};
2
3use crate::Error;
4
5pub struct Session {
11 session: Box<dyn SessionInner>,
12 closed: bool,
13}
14
15impl Session {
16 pub(super) fn new<S: web_transport_trait::Session>(session: S) -> Self {
17 Self {
18 session: Box::new(session),
19 closed: false,
20 }
21 }
22
23 pub fn close(&mut self, err: Error) {
25 if self.closed {
26 return;
27 }
28 self.closed = true;
29 self.session.close(err.to_code(), err.to_string().as_ref());
30 }
31
32 pub async fn closed(&self) -> Result<(), Error> {
35 self.session.closed().await;
36 Err(Error::Transport)
37 }
38}
39
40impl Drop for Session {
41 fn drop(&mut self) {
42 if !self.closed {
43 self.session.close(Error::Cancel.to_code(), "dropped");
44 }
45 }
46}
47
48trait SessionInner: Send + Sync {
50 fn close(&self, code: u32, reason: &str);
51 fn closed(&self) -> Pin<Box<dyn Future<Output = ()> + Send + '_>>;
52}
53
54impl<S: web_transport_trait::Session> SessionInner for S {
55 fn close(&self, code: u32, reason: &str) {
56 S::close(self, code, reason);
57 }
58
59 fn closed(&self) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
60 Box::pin(async move {
61 let _ = S::closed(self).await;
62 })
63 }
64}