tls_api/
stream_with_socket.rs

1use std::fmt;
2use std::ops::Deref;
3use std::ops::DerefMut;
4use std::pin::Pin;
5
6use crate::assert_kinds::assert_socket;
7use crate::assert_send;
8use crate::runtime::AsyncRead;
9use crate::runtime::AsyncWrite;
10use crate::socket::AsyncSocket;
11use crate::spi::TlsStreamWithUpcastDyn;
12use crate::spi_async_socket_impl_delegate;
13use crate::ImplInfo;
14use crate::TlsStream;
15use crate::TlsStreamDyn;
16use crate::TlsStreamWithSocketDyn;
17
18/// TLS stream object returned by `connect_with_socket` and `accept_with_socket` operations.
19///
20/// Since Rust has no HKT, it is not possible to declare something like
21///
22/// ```ignore
23/// trait TlsConnector {
24///     type <S> TlsStream<S> : TlsStreamImpl;
25/// }
26/// ```
27///
28/// So `TlsStream` is actually a box to concrete TLS implementation.
29/// So each operation perform a virtual call (which is not a big deal for sockets).
30///
31/// This type is parameterized by socket type, [`TlsStream`] is simpler version of this stream.
32pub struct TlsStreamWithSocket<S: AsyncSocket>(pub(crate) Box<dyn TlsStreamWithUpcastDyn<S>>);
33
34fn _assert_kinds<S: AsyncRead + AsyncWrite + fmt::Debug + Unpin + Send + 'static>() {
35    assert_send::<TlsStreamWithSocket<S>>();
36    assert_socket::<TlsStreamWithSocket<S>>();
37}
38
39impl<S: AsyncSocket> fmt::Debug for TlsStreamWithSocket<S> {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        f.debug_tuple("TlsStream").field(&self.0).finish()
42    }
43}
44
45impl<S: AsyncSocket> TlsStreamDyn for TlsStreamWithSocket<S> {
46    fn get_alpn_protocol(&self) -> anyhow::Result<Option<Vec<u8>>> {
47        self.0.get_alpn_protocol()
48    }
49
50    fn impl_info(&self) -> ImplInfo {
51        self.0.impl_info()
52    }
53
54    fn get_socket_dyn_mut(&mut self) -> &mut dyn AsyncSocket {
55        self.0.get_socket_dyn_mut()
56    }
57
58    fn get_socket_dyn_ref(&self) -> &dyn AsyncSocket {
59        self.0.get_socket_dyn_ref()
60    }
61}
62
63impl<S: AsyncSocket> TlsStreamWithSocketDyn<S> for TlsStreamWithSocket<S> {
64    /// Get a reference the underlying TLS-wrapped socket.
65    fn get_socket_mut(&mut self) -> &mut S {
66        self.0.get_socket_mut()
67    }
68
69    /// Get a reference the underlying TLS-wrapped socket.
70    fn get_socket_ref(&self) -> &S {
71        self.0.get_socket_ref()
72    }
73}
74
75impl<S: AsyncSocket> TlsStreamWithSocket<S> {
76    /// Construct a stream from a stream implementation.
77    ///
78    /// This function is intended to be used by API implementors, not by users.
79    pub fn new<I: TlsStreamWithUpcastDyn<S>>(imp: I) -> TlsStreamWithSocket<S> {
80        TlsStreamWithSocket(Box::new(imp))
81    }
82
83    /// Convert to a functionally and performance identical TLS stream object
84    /// but without socket type parameter.
85    pub fn without_type_parameter(self) -> TlsStream {
86        TlsStream::new(self)
87    }
88
89    fn deref_pin_mut_for_impl_socket(
90        self: Pin<&mut Self>,
91    ) -> Pin<&mut dyn TlsStreamWithUpcastDyn<S>> {
92        Pin::new(&mut *self.get_mut().0)
93    }
94
95    #[allow(dead_code)]
96    fn deref_for_impl_socket(&self) -> &dyn TlsStreamWithUpcastDyn<S> {
97        &*self.0
98    }
99}
100
101impl<S: AsyncSocket> Deref for TlsStreamWithSocket<S> {
102    type Target = dyn TlsStreamWithUpcastDyn<S>;
103
104    fn deref(&self) -> &Self::Target {
105        &*self.0
106    }
107}
108
109impl<S: AsyncSocket> DerefMut for TlsStreamWithSocket<S> {
110    fn deref_mut(&mut self) -> &mut Self::Target {
111        &mut *self.0
112    }
113}
114
115spi_async_socket_impl_delegate!(TlsStreamWithSocket<S>);