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