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        #[inline]
14        fn spawn_obj(&self, future: futures::future::FutureObj<'static, ()>) -> Result<(), futures::task::SpawnError> {
15            self.$member.spawn_obj(future)
16        }
17    }
18
19    impl $crate::traits::Blocking for $t {
20        type ThreadHandle<T: Send + 'static> = <$mty as $crate::traits::Blocking>::ThreadHandle<T>;
21
22        #[inline]
23        fn spawn_blocking<F, T>(&self, f: F) -> <$mty as $crate::traits::Blocking>::ThreadHandle<T>
24        where
25            F: FnOnce() -> T + Send + 'static,
26            T: Send + 'static,
27        {
28            self.$member.spawn_blocking(f)
29        }
30
31        #[inline]
32        fn reenter_block_on<F>(&self, future: F) -> F::Output
33        where
34            F: futures::Future,
35            F::Output: Send + 'static
36        {
37            self.$member.reenter_block_on(future)
38        }
39    }
40
41    impl $crate::traits::ToplevelBlockOn for $t {
42        #[inline]
43        fn block_on<F: futures::Future>(&self, future: F) -> F::Output {
44            self.$member.block_on(future)
45        }
46
47    }
48
49    impl $crate::traits::SleepProvider for $t {
50        type SleepFuture = <$mty as $crate::traits::SleepProvider>::SleepFuture;
51        #[inline]
52        fn sleep(&self, duration: std::time::Duration) -> Self::SleepFuture {
53            self.$member.sleep(duration)
54        }
55    }
56
57    impl $crate::CoarseTimeProvider for $t {
58        #[inline]
59        fn now_coarse(&self) -> $crate::CoarseInstant {
60            self.$member.now_coarse()
61        }
62    }
63
64    #[async_trait::async_trait]
65    impl $crate::traits::NetStreamProvider<std::net::SocketAddr> for $t {
66        type Stream = <$mty as $crate::traits::NetStreamProvider>::Stream;
67        type Listener = <$mty as $crate::traits::NetStreamProvider>::Listener;
68        #[inline]
69        async fn connect(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::Stream> {
70            self.$member.connect(addr).await
71        }
72        #[inline]
73        async fn listen(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::Listener> {
74            self.$member.listen(addr).await
75        }
76    }
77    #[async_trait::async_trait]
78    impl $crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr> for $t {
79        type Stream = <$mty as $crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr>>::Stream;
80        type Listener = <$mty as $crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr>>::Listener;
81        #[inline]
82        async fn connect(&self, addr: &tor_general_addr::unix::SocketAddr) -> std::io::Result<Self::Stream> {
83            self.$member.connect(addr).await
84        }
85        #[inline]
86        async fn listen(&self, addr: &tor_general_addr::unix::SocketAddr) -> std::io::Result<Self::Listener> {
87            self.$member.listen(addr).await
88        }
89    }
90
91    impl<S> $crate::traits::TlsProvider<S> for $t
92    where S: futures::AsyncRead + futures::AsyncWrite + $crate::traits::StreamOps + Unpin + Send + 'static,
93    {
94        type Connector = <$mty as $crate::traits::TlsProvider<S>>::Connector;
95        type TlsStream = <$mty as $crate::traits::TlsProvider<S>>::TlsStream;
96        #[inline]
97        fn tls_connector(&self) -> Self::Connector {
98            self.$member.tls_connector()
99        }
100        #[inline]
101        fn supports_keying_material_export(&self) -> bool {
102            <$mty as $crate::traits::TlsProvider<S>>::supports_keying_material_export(&self.$member)
103        }
104    }
105
106    #[async_trait::async_trait]
107    impl $crate::traits::UdpProvider for $t {
108        type UdpSocket = <$mty as $crate::traits::UdpProvider>::UdpSocket;
109
110        #[inline]
111        async fn bind(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::UdpSocket> {
112            self.$member.bind(addr).await
113        }
114    }
115
116    impl std::fmt::Debug for $t {
117        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118            f.debug_struct(stringify!($t)).finish_non_exhaustive()
119        }
120    }
121
122    // This boilerplate will fail unless $t implements Runtime.
123    const _ : () = {
124        fn assert_runtime<R: $crate::Runtime>() {}
125        fn check() {
126            assert_runtime::<$t>();
127        }
128    };
129}
130}
131
132#[allow(unused)] // Can be unused if no runtimes are declared.
133pub(crate) use implement_opaque_runtime;