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
351
        fn spawn_obj(&self, future: futures::future::FutureObj<'static, ()>) -> Result<(), futures::task::SpawnError> {
15
351
            self.$member.spawn_obj(future)
16
351
        }
17
    }
18

            
19
    impl $crate::traits::BlockOn for $t {
20
        #[inline]
21
310
        fn block_on<F: futures::Future>(&self, future: F) -> F::Output {
22
310
            self.$member.block_on(future)
23
310
        }
24

            
25
    }
26

            
27
    impl $crate::traits::SleepProvider for $t {
28
        type SleepFuture = <$mty as $crate::traits::SleepProvider>::SleepFuture;
29
        #[inline]
30
102
        fn sleep(&self, duration: std::time::Duration) -> Self::SleepFuture {
31
102
            self.$member.sleep(duration)
32
102
        }
33
    }
34

            
35
    #[async_trait::async_trait]
36
    impl $crate::traits::TcpProvider for $t {
37
        type TcpStream = <$mty as $crate::traits::TcpProvider>::TcpStream;
38
        type TcpListener = <$mty as $crate::traits::TcpProvider>::TcpListener;
39
        #[inline]
40
34
        async fn connect(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::TcpStream> {
41
            self.$member.connect(addr).await
42
        }
43
        #[inline]
44
8
        async fn listen(&self, addr: &std::net::SocketAddr) -> std::io::Result<Self::TcpListener> {
45
            self.$member.listen(addr).await
46
        }
47
    }
48

            
49
    impl<S> $crate::traits::TlsProvider<S> for $t
50
    where S: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static,
51
    {
52
        type Connector = <$mty as $crate::traits::TlsProvider<S>>::Connector;
53
        type TlsStream = <$mty as $crate::traits::TlsProvider<S>>::TlsStream;
54
        #[inline]
55
26
        fn tls_connector(&self) -> Self::Connector {
56
26
            self.$member.tls_connector()
57
26
        }
58
    }
59

            
60
    impl std::fmt::Debug for $t {
61
4
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62
4
            f.debug_struct(stringify!($t)).finish_non_exhaustive()
63
4
        }
64
    }
65

            
66
    // This boilerplate will fail unless $t implements Runtime.
67
    const _ : () = {
68
        fn assert_runtime<R: $crate::Runtime>() {}
69
        fn check() {
70
            assert_runtime::<$t>();
71
        }
72
    };
73
}
74
}
75

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