Skip to main content

tor_rtcompat/
opaque.rs

1//! Declare a macro for making opaque runtime wrappers.
2
3/// Implement delegating implementations of the runtime traits for a type $t
4/// whose member $r implements Runtime.  Used to hide the details of the
5/// implementation of $t.
6#[allow(unused)] // Can be unused if no runtimes are declared.
7macro_rules! implement_opaque_runtime {
8{
9    $t:ty { $member:ident : $mty:ty }
10} => {
11
12    impl futures::task::Spawn for $t {
13        // `track_caller` required for tokio-console
14        #[inline]
15        #[track_caller]
16        fn spawn_obj(&self, future: futures::future::FutureObj<'static, ()>) -> Result<(), futures::task::SpawnError> {
17            self.$member.spawn_obj(future)
18        }
19    }
20
21    impl $crate::traits::Blocking for $t {
22        type ThreadHandle<T: Send + 'static> = <$mty as $crate::traits::Blocking>::ThreadHandle<T>;
23
24        // `track_caller` required for tokio-console
25        #[inline]
26        #[track_caller]
27        fn spawn_blocking<F, T>(&self, f: F) -> <$mty as $crate::traits::Blocking>::ThreadHandle<T>
28        where
29            F: FnOnce() -> T + Send + 'static,
30            T: Send + 'static,
31        {
32            self.$member.spawn_blocking(f)
33        }
34
35        // `track_caller` required for tokio-console
36        #[inline]
37        #[track_caller]
38        fn reenter_block_on<F>(&self, future: F) -> F::Output
39        where
40            F: futures::Future,
41            F::Output: Send + 'static
42        {
43            self.$member.reenter_block_on(future)
44        }
45    }
46
47    impl $crate::traits::ToplevelBlockOn for $t {
48        // `track_caller` required for tokio-console
49        #[inline]
50        #[track_caller]
51        fn block_on<F: futures::Future>(&self, future: F) -> F::Output {
52            self.$member.block_on(future)
53        }
54
55    }
56
57    impl $crate::traits::SleepProvider for $t {
58        type SleepFuture = <$mty as $crate::traits::SleepProvider>::SleepFuture;
59        #[inline]
60        fn sleep(&self, duration: std::time::Duration) -> Self::SleepFuture {
61            self.$member.sleep(duration)
62        }
63    }
64
65    impl $crate::CoarseTimeProvider for $t {
66        #[inline]
67        fn now_coarse(&self) -> $crate::CoarseInstant {
68            self.$member.now_coarse()
69        }
70    }
71
72    #[async_trait::async_trait]
73    impl $crate::traits::NetStreamProvider<std::net::SocketAddr> for $t {
74        type Stream = <$mty as $crate::traits::NetStreamProvider>::Stream;
75        type Listener = <$mty as $crate::traits::NetStreamProvider>::Listener;
76        type ConnectOptions = <$mty as $crate::traits::NetStreamProvider>::ConnectOptions;
77        type ListenOptions = <$mty as $crate::traits::NetStreamProvider>::ListenOptions;
78        #[inline]
79        #[tracing::instrument(skip_all, level = "trace")]
80        async fn connect(
81            &self,
82            addr: &std::net::SocketAddr,
83            options: &Self::ConnectOptions,
84        ) -> std::io::Result<Self::Stream> {
85            self.$member.connect(addr, options).await
86        }
87        #[inline]
88        async fn listen(
89            &self,
90            addr: &std::net::SocketAddr,
91            options: &Self::ListenOptions,
92        ) -> std::io::Result<Self::Listener> {
93            self.$member.listen(addr, options).await
94        }
95    }
96    #[async_trait::async_trait]
97    impl $crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr> for $t {
98        type Stream = <$mty as $crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr>>::Stream;
99        type Listener = <$mty as $crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr>>::Listener;
100        type ConnectOptions = <$mty as $crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr>>::ConnectOptions;
101        type ListenOptions = <$mty as $crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr>>::ListenOptions;
102        #[inline]
103        #[tracing::instrument(skip_all, level = "trace")]
104        async fn connect(
105            &self,
106            addr: &tor_general_addr::unix::SocketAddr,
107            options: &Self::ConnectOptions,
108        ) -> std::io::Result<Self::Stream> {
109            self.$member.connect(addr, options).await
110        }
111        #[inline]
112        async fn listen(
113            &self,
114            addr: &tor_general_addr::unix::SocketAddr,
115            options: &Self::ListenOptions,
116        ) -> std::io::Result<Self::Listener> {
117            self.$member.listen(addr, options).await
118        }
119    }
120
121    impl<S> $crate::traits::TlsProvider<S> for $t
122    where S: futures::AsyncRead + futures::AsyncWrite + $crate::traits::StreamOps + Unpin + Send + 'static,
123    {
124        type Connector = <$mty as $crate::traits::TlsProvider<S>>::Connector;
125        type TlsStream = <$mty as $crate::traits::TlsProvider<S>>::TlsStream;
126        type Acceptor = <$mty as $crate::traits::TlsProvider<S>>::Acceptor;
127        type TlsServerStream = <$mty as $crate::traits::TlsProvider<S>>::TlsServerStream;
128
129        #[inline]
130        fn tls_connector(&self) -> Self::Connector {
131            self.$member.tls_connector()
132        }
133        #[inline]
134        fn tls_acceptor(&self, settings: $crate::traits::TlsAcceptorSettings) -> std::io::Result<Self::Acceptor> {
135           <$mty as $crate::traits::TlsProvider<S>>::tls_acceptor(&self.$member, settings)
136        }
137        #[inline]
138        fn supports_keying_material_export(&self) -> bool {
139            <$mty as $crate::traits::TlsProvider<S>>::supports_keying_material_export(&self.$member)
140        }
141    }
142
143    #[async_trait::async_trait]
144    impl $crate::traits::UdpProvider for $t {
145        type UdpSocket = <$mty as $crate::traits::UdpProvider>::UdpSocket;
146
147        #[inline]
148        async fn bind(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::UdpSocket> {
149            self.$member.bind(addr).await
150        }
151    }
152
153    impl std::fmt::Debug for $t {
154        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155            f.debug_struct(stringify!($t)).finish_non_exhaustive()
156        }
157    }
158
159    // This boilerplate will fail unless $t implements Runtime.
160    #[allow(unused)]
161    const _ : () = {
162        fn assert_runtime<R: $crate::Runtime>() {}
163        fn check() {
164            assert_runtime::<$t>();
165        }
166    };
167}
168}
169
170#[allow(unused)] // Can be unused if no runtimes are declared.
171pub(crate) use implement_opaque_runtime;