//! Declare MockNetRuntime. // TODO(nickm): This is mostly copy-paste from MockSleepRuntime. If possible, // we should make it so that more code is more shared. use crate::net::MockNetProvider; use tor_rtcompat::{BlockOn, Runtime, SleepProvider, TcpProvider, TlsProvider}; use crate::io::LocalStream; use async_trait::async_trait; use futures::task::{FutureObj, Spawn, SpawnError}; use futures::Future; use std::io::Result as IoResult; use std::net::SocketAddr; use std::time::{Duration, Instant, SystemTime}; /// A wrapper Runtime that overrides the SleepProvider trait for the /// underlying runtime. #[derive(Clone)] pub struct MockNetRuntime { /// The underlying runtime. Most calls get delegated here. runtime: R, /// A MockNetProvider. Time-related calls get delegated here. net: MockNetProvider, } impl MockNetRuntime { /// Create a new runtime that wraps `runtime`, but overrides /// its view of the network with a [`MockNetProvider`], `net`. pub fn new(runtime: R, net: MockNetProvider) -> Self { MockNetRuntime { runtime, net } } /// Return a reference to the underlying runtime. pub fn inner(&self) -> &R { &self.runtime } /// Return a reference to the [`MockNetProvider`] pub fn mock_net(&self) -> &MockNetProvider { &self.net } } impl Spawn for MockNetRuntime { fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> { self.runtime.spawn_obj(future) } } impl BlockOn for MockNetRuntime { fn block_on(&self, future: F) -> F::Output { self.runtime.block_on(future) } } #[async_trait] impl TcpProvider for MockNetRuntime { type TcpStream = ::TcpStream; type TcpListener = ::TcpListener; async fn connect(&self, addr: &SocketAddr) -> IoResult { self.net.connect(addr).await } async fn listen(&self, addr: &SocketAddr) -> IoResult { self.net.listen(addr).await } } impl TlsProvider for MockNetRuntime { type Connector = >::Connector; type TlsStream = >::TlsStream; fn tls_connector(&self) -> Self::Connector { self.net.tls_connector() } } impl SleepProvider for MockNetRuntime { type SleepFuture = R::SleepFuture; fn sleep(&self, dur: Duration) -> Self::SleepFuture { self.runtime.sleep(dur) } fn now(&self) -> Instant { self.runtime.now() } fn wallclock(&self) -> SystemTime { self.runtime.wallclock() } }