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.
7
macro_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
1038
        fn spawn_obj(&self, future: futures::future::FutureObj<'static, ()>) -> Result<(), futures::task::SpawnError> {
17
1038
            self.$member.spawn_obj(future)
18
1038
        }
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
1208
        fn block_on<F: futures::Future>(&self, future: F) -> F::Output {
52
1208
            self.$member.block_on(future)
53
1208
        }
54

            
55
    }
56

            
57
    impl $crate::traits::SleepProvider for $t {
58
        type SleepFuture = <$mty as $crate::traits::SleepProvider>::SleepFuture;
59
        #[inline]
60
1814
        fn sleep(&self, duration: std::time::Duration) -> Self::SleepFuture {
61
1814
            self.$member.sleep(duration)
62
1814
        }
63
    }
64

            
65
    impl $crate::CoarseTimeProvider for $t {
66
        #[inline]
67
2427
        fn now_coarse(&self) -> $crate::CoarseInstant {
68
2427
            self.$member.now_coarse()
69
2427
        }
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
26
        }
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
30
        fn tls_connector(&self) -> Self::Connector {
131
30
            self.$member.tls_connector()
132
30
        }
133
        #[inline]
134
16
        fn tls_acceptor(&self, settings: $crate::traits::TlsAcceptorSettings) -> std::io::Result<Self::Acceptor> {
135
16
           <$mty as $crate::traits::TlsProvider<S>>::tls_acceptor(&self.$member, settings)
136
16
        }
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
20
        }
151
    }
152

            
153
    impl std::fmt::Debug for $t {
154
4186
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155
4186
            f.debug_struct(stringify!($t)).finish_non_exhaustive()
156
4186
        }
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.
171
pub(crate) use implement_opaque_runtime;