1use derive_deftly::define_derive_deftly;
4use futures::channel::mpsc;
5
6define_derive_deftly! {
7SomeMockRuntime for struct, expect items, beta_deftly:
26
27 $(
28 ${when fmeta(mock(task))}
29
30 impl <$tgens> Spawn for $ttype {
31 fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
32 self.$fname.spawn_obj(future)
33 }
34 }
35
36 impl <$tgens> Blocking for $ttype {
37 type ThreadHandle<T: Send + 'static> = <$ftype as Blocking>::ThreadHandle<T>;
38
39 fn spawn_blocking<F, T>(&self, f: F) -> <$ftype as Blocking>::ThreadHandle<T>
40 where
41 F: FnOnce() -> T + Send + 'static,
42 T: Send + 'static {
43 self.$fname.spawn_blocking(f)
44 }
45
46 fn reenter_block_on<F>(&self, future: F) -> F::Output
47 where
48 F: Future,
49 F::Output: Send + 'static
50 {
51 self.$fname.reenter_block_on(future)
52 }
53 }
54
55 )
56 $(
57 ${when any(fmeta(mock(toplevel)), fmeta(mock(toplevel_where)))}
58
59 impl <$tgens> ToplevelBlockOn for $ttype
60 where ${fmeta(mock(toplevel_where)) as token_stream, default {}}
61 {
62 fn block_on<F: Future>(&self, future: F) -> F::Output {
63 self.$fname.block_on(future)
64 }
65 }
66
67 )
68 $(
69 ${when fmeta(mock(net))}
70
71 #[async_trait]
72 impl <$tgens> NetStreamProvider for $ttype {
73 type Stream = <$ftype as NetStreamProvider>::Stream;
74 type Listener = <$ftype as NetStreamProvider>::Listener;
75 type ConnectOptions = <$ftype as NetStreamProvider>::ConnectOptions;
76 type ListenOptions = <$ftype as NetStreamProvider>::ListenOptions;
77
78 async fn connect(
79 &self,
80 addr: &SocketAddr,
81 options: &Self::ConnectOptions,
82 ) -> IoResult<Self::Stream> {
83 self.$fname.connect(addr, options).await
84 }
85 async fn listen(
86 &self,
87 addr: &SocketAddr,
88 options: &Self::ListenOptions,
89 ) -> IoResult<Self::Listener> {
90 self.$fname.listen(addr, options).await
91 }
92 }
93
94 #[async_trait]
95 impl <$tgens> NetStreamProvider<tor_general_addr::unix::SocketAddr> for $ttype {
96 type Stream = FakeStream;
97 type Listener = FakeListener<tor_general_addr::unix::SocketAddr>;
98 type ConnectOptions = tor_rtcompat::UnixConnectOptions;
99 type ListenOptions = tor_rtcompat::UnixListenOptions;
100
101 async fn connect(
102 &self,
103 _addr: &tor_general_addr::unix::SocketAddr,
104 _options: &Self::ConnectOptions,
105 ) -> IoResult<Self::Stream> {
106 Err(tor_general_addr::unix::NoAfUnixSocketSupport::default().into())
107 }
108 async fn listen(
109 &self,
110 _addr: &tor_general_addr::unix::SocketAddr,
111 _options: &Self::ListenOptions,
112 ) -> IoResult<Self::Listener> {
113 Err(tor_general_addr::unix::NoAfUnixSocketSupport::default().into())
114 }
115 }
116
117 impl <$tgens> TlsProvider<<$ftype as NetStreamProvider>::Stream> for $ttype {
118 type Connector = <$ftype as TlsProvider<
119 <$ftype as NetStreamProvider>::Stream
120 >>::Connector;
121 type TlsStream = <$ftype as TlsProvider<
122 <$ftype as NetStreamProvider>::Stream
123 >>::TlsStream;
124 type Acceptor = <$ftype as TlsProvider<
125 <$ftype as NetStreamProvider>::Stream
126 >>::Acceptor;
127 type TlsServerStream = <$ftype as TlsProvider<
128 <$ftype as NetStreamProvider>::Stream
129 >>::TlsServerStream;
130
131 fn tls_connector(&self) -> Self::Connector {
132 self.$fname.tls_connector()
133 }
134 fn tls_acceptor(&self, settings: tor_rtcompat::tls::TlsAcceptorSettings) -> std::io::Result<Self::Acceptor> {
135 self.$fname.tls_acceptor(settings)
136 }
137 fn supports_keying_material_export(&self) -> bool {
138 self.$fname.supports_keying_material_export()
139 }
140 }
141
142 #[async_trait]
143 impl <$tgens> UdpProvider for $ttype {
144 type UdpSocket = <$ftype as UdpProvider>::UdpSocket;
145
146 #[inline]
147 async fn bind(&self, addr: &SocketAddr) -> IoResult<Self::UdpSocket> {
148 self.$fname.bind(addr).await
149 }
150 }
151
152 )
153 $(
154 ${when fmeta(mock(sleep))}
155
156 impl <$tgens> SleepProvider for $ttype {
157 type SleepFuture = <$ftype as SleepProvider>::SleepFuture;
158
159 fn sleep(&self, dur: Duration) -> Self::SleepFuture {
160 self.$fname.sleep(dur)
161 }
162 fn now(&self) -> Instant {
163 self.$fname.now()
164 }
165 fn wallclock(&self) -> SystemTime {
166 self.$fname.wallclock()
167 }
168 fn block_advance<T: Into<String>>(&self, reason: T) {
169 self.$fname.block_advance(reason);
170 }
171 fn release_advance<T: Into<String>>(&self, reason: T) {
172 self.$fname.release_advance(reason);
173 }
174 fn allow_one_advance(&self, dur: Duration) {
175 self.$fname.allow_one_advance(dur);
176 }
177 }
178
179 impl <$tgens> CoarseTimeProvider for $ttype {
180 fn now_coarse(&self) -> CoarseInstant {
181 self.$fname.now_coarse()
182 }
183 }
184
185 )
186
187 #[allow(unused)]
189 const _: fn() = || {
190 fn x(_: impl Runtime) { }
191 fn check_impl_runtime<$tgens>(t: $ttype) { x(t) }
192 };
193}
194
195pub(crate) mod impl_runtime_prelude {
207 pub(crate) use async_trait::async_trait;
208 pub(crate) use derive_deftly::Deftly;
209 pub(crate) use futures::Future;
210 pub(crate) use futures::task::{FutureObj, Spawn, SpawnError};
211 pub(crate) use std::io::Result as IoResult;
212 pub(crate) use std::net::SocketAddr;
213 pub(crate) use tor_rtcompat::{
214 Blocking, CoarseInstant, CoarseTimeProvider, NetStreamProvider, Runtime, SleepProvider,
215 TlsProvider, ToplevelBlockOn, UdpProvider, unimpl::FakeListener, unimpl::FakeStream,
216 };
217 pub(crate) use web_time_compat::{Duration, Instant, SystemTime, SystemTimeExt};
218}
219
220#[allow(clippy::disallowed_methods)]
227pub(crate) fn mpsc_channel<T>(buffer: usize) -> (mpsc::Sender<T>, mpsc::Receiver<T>) {
228 mpsc::channel(buffer)
229}