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
        #[inline]
14
926
        fn spawn_obj(&self, future: futures::future::FutureObj<'static, ()>) -> Result<(), futures::task::SpawnError> {
15
926
            self.$member.spawn_obj(future)
16
926
        }
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
824
        fn block_on<F: futures::Future>(&self, future: F) -> F::Output {
44
824
            self.$member.block_on(future)
45
824
        }
46

            
47
    }
48

            
49
    impl $crate::traits::SleepProvider for $t {
50
        type SleepFuture = <$mty as $crate::traits::SleepProvider>::SleepFuture;
51
        #[inline]
52
524
        fn sleep(&self, duration: std::time::Duration) -> Self::SleepFuture {
53
524
            self.$member.sleep(duration)
54
524
        }
55
    }
56

            
57
    impl $crate::CoarseTimeProvider for $t {
58
        #[inline]
59
1605
        fn now_coarse(&self) -> $crate::CoarseInstant {
60
1605
            self.$member.now_coarse()
61
1605
        }
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
102
        async fn connect(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::Stream> {
70
68
            self.$member.connect(addr).await
71
136
        }
72
        #[inline]
73
24
        async fn listen(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::Listener> {
74
16
            self.$member.listen(addr).await
75
32
        }
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
34
        fn tls_connector(&self) -> Self::Connector {
98
34
            self.$member.tls_connector()
99
34
        }
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
24
        async fn bind(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::UdpSocket> {
112
16
            self.$member.bind(addr).await
113
32
        }
114
    }
115

            
116
    impl std::fmt::Debug for $t {
117
740
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118
740
            f.debug_struct(stringify!($t)).finish_non_exhaustive()
119
740
        }
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.
133
pub(crate) use implement_opaque_runtime;