Skip to main content

async_rs/implementors/
noop.rs

1//! noop implementation of async runtime definition traits
2
3use crate::{
4    Runtime,
5    sys::AsSysFd,
6    traits::{Executor, Reactor, RuntimeKit},
7    util::{self, DummyIO, DummyStream, Task},
8};
9use futures_core::Stream;
10use futures_io::{AsyncRead, AsyncWrite};
11use std::{
12    future::{self, Future, Ready},
13    io::{self, Read, Write},
14    marker::PhantomData,
15    net::SocketAddr,
16    time::{Duration, Instant},
17};
18
19use task::NTask;
20
21/// Type alias for the noop runtime
22pub type NoopRuntime = Runtime<Noop>;
23
24impl NoopRuntime {
25    /// Create a new NoopRuntime
26    #[must_use]
27    pub fn noop() -> Self {
28        Self::new(Noop)
29    }
30}
31
32/// A no-op [`RuntimeKit`] implementation that never actually executes tasks or I/O
33#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
34pub struct Noop;
35
36impl RuntimeKit for Noop {}
37
38impl Executor for Noop {
39    type Task<T: Send + 'static> = NTask<T>;
40
41    fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
42        // We cannot fake something unless we require T: Default, which we don't want.
43        // Let's get a minimalist implementation for this one.
44        util::simple_block_on(f)
45    }
46
47    fn spawn<T: Send + 'static, F: Future<Output = T> + Send + 'static>(
48        &self,
49        _f: F,
50    ) -> Task<Self::Task<T>> {
51        NTask(PhantomData).into()
52    }
53
54    fn spawn_blocking<T: Send + 'static, F: FnOnce() -> T + Send + 'static>(
55        &self,
56        _f: F,
57    ) -> Task<Self::Task<T>> {
58        NTask(PhantomData).into()
59    }
60}
61
62impl Reactor for Noop {
63    type TcpStream = DummyIO;
64    type Sleep = Ready<()>;
65
66    fn register<H: Read + Write + AsSysFd + Send + 'static>(
67        &self,
68        _socket: H,
69    ) -> io::Result<impl AsyncRead + AsyncWrite + Send + Unpin + 'static> {
70        Ok(DummyIO)
71    }
72
73    fn sleep(&self, _dur: Duration) -> Self::Sleep {
74        future::ready(())
75    }
76
77    fn interval(&self, _dur: Duration) -> impl Stream<Item = Instant> + Send + 'static {
78        DummyStream(PhantomData)
79    }
80
81    fn tcp_connect_addr(
82        &self,
83        _addr: SocketAddr,
84    ) -> impl Future<Output = io::Result<Self::TcpStream>> + Send + 'static {
85        async { Ok(DummyIO) }
86    }
87}
88
89mod task {
90    use crate::util::TaskImpl;
91    use async_trait::async_trait;
92    use std::{
93        future::Future,
94        marker::PhantomData,
95        pin::Pin,
96        task::{Context, Poll},
97    };
98
99    /// A noop task
100    #[derive(Debug)]
101    pub struct NTask<T: Send + 'static>(pub(super) PhantomData<T>);
102
103    impl<T: Send + 'static> Unpin for NTask<T> {}
104
105    #[async_trait]
106    impl<T: Send + 'static> TaskImpl for NTask<T> {}
107
108    impl<T: Send + 'static> Future for NTask<T> {
109        type Output = T;
110
111        fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
112            Poll::Pending
113        }
114    }
115}
116
117#[cfg(test)]
118mod tests {
119    use super::*;
120
121    #[test]
122    fn auto_traits() {
123        use crate::util::test::*;
124        let runtime = Runtime::noop();
125        assert_send(&runtime);
126        assert_sync(&runtime);
127        assert_clone(&runtime);
128    }
129}