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

            
55
    }
56

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

            
65
    impl $crate::CoarseTimeProvider for $t {
66
        #[inline]
67
2428
        fn now_coarse(&self) -> $crate::CoarseInstant {
68
2428
            self.$member.now_coarse()
69
2428
        }
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
        #[inline]
77
        #[tracing::instrument(skip_all, level = "trace")]
78
        async fn connect(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::Stream> {
79
            self.$member.connect(addr).await
80
        }
81
        #[inline]
82
26
        async fn listen(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::Listener> {
83
            self.$member.listen(addr).await
84
26
        }
85
    }
86
    #[async_trait::async_trait]
87
    impl $crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr> for $t {
88
        type Stream = <$mty as $crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr>>::Stream;
89
        type Listener = <$mty as $crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr>>::Listener;
90
        #[inline]
91
        #[tracing::instrument(skip_all, level = "trace")]
92
        async fn connect(&self, addr: &tor_general_addr::unix::SocketAddr) -> std::io::Result<Self::Stream> {
93
            self.$member.connect(addr).await
94
        }
95
        #[inline]
96
        async fn listen(&self, addr: &tor_general_addr::unix::SocketAddr) -> std::io::Result<Self::Listener> {
97
            self.$member.listen(addr).await
98
        }
99
    }
100

            
101
    impl<S> $crate::traits::TlsProvider<S> for $t
102
    where S: futures::AsyncRead + futures::AsyncWrite + $crate::traits::StreamOps + Unpin + Send + 'static,
103
    {
104
        type Connector = <$mty as $crate::traits::TlsProvider<S>>::Connector;
105
        type TlsStream = <$mty as $crate::traits::TlsProvider<S>>::TlsStream;
106
        type Acceptor = <$mty as $crate::traits::TlsProvider<S>>::Acceptor;
107
        type TlsServerStream = <$mty as $crate::traits::TlsProvider<S>>::TlsServerStream;
108

            
109
        #[inline]
110
56
        fn tls_connector(&self) -> Self::Connector {
111
56
            self.$member.tls_connector()
112
56
        }
113
        #[inline]
114
16
        fn tls_acceptor(&self, settings: $crate::traits::TlsAcceptorSettings) -> std::io::Result<Self::Acceptor> {
115
16
           <$mty as $crate::traits::TlsProvider<S>>::tls_acceptor(&self.$member, settings)
116
16
        }
117
        #[inline]
118
        fn supports_keying_material_export(&self) -> bool {
119
            <$mty as $crate::traits::TlsProvider<S>>::supports_keying_material_export(&self.$member)
120
        }
121
    }
122

            
123
    #[async_trait::async_trait]
124
    impl $crate::traits::UdpProvider for $t {
125
        type UdpSocket = <$mty as $crate::traits::UdpProvider>::UdpSocket;
126

            
127
        #[inline]
128
20
        async fn bind(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::UdpSocket> {
129
            self.$member.bind(addr).await
130
20
        }
131
    }
132

            
133
    impl std::fmt::Debug for $t {
134
3743
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135
3743
            f.debug_struct(stringify!($t)).finish_non_exhaustive()
136
3743
        }
137
    }
138

            
139
    // This boilerplate will fail unless $t implements Runtime.
140
    #[allow(unused)]
141
    const _ : () = {
142
        fn assert_runtime<R: $crate::Runtime>() {}
143
        fn check() {
144
            assert_runtime::<$t>();
145
        }
146
    };
147
}
148
}
149

            
150
#[allow(unused)] // Can be unused if no runtimes are declared.
151
pub(crate) use implement_opaque_runtime;