1extern crate alloc;
2
3use crate::BoxFuture;
4use alloc::boxed::Box;
5use core::future::Future;
6use core::ops::Deref;
7use core::pin::Pin;
8use core::task::{Context, Poll};
9use core::time::Duration;
10
11pub enum Never {}
13impl Never { pub fn into(self) -> ! { loop {} } }
14
15pub struct Stop;
17
18impl Future for Stop {
19 type Output = Never;
20
21 fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
22 Poll::Pending }
24}
25
26pub struct SpawnedFuture<'a>(u64, &'a mut dyn InternalRuntime);
28
29impl<'a> Future for SpawnedFuture<'a> {
30 type Output = ();
31
32 fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
33 let me = self.get_mut();
34 if me.1.contains(me.0) {
35 Poll::Pending
36 } else {
37 Poll::Ready(())
38 }
39 }
40}
41
42pub trait InternalRuntime {
44 fn push_boxed(&mut self, future: BoxFuture<'static, ()>) -> u64;
46 fn contains(&mut self, id: u64) -> bool;
48 fn sleep<'a>(&self, duration: Duration) -> BoxFuture<'a, ()>;
50 fn stop(&mut self) -> Stop;
52}
53pub trait Runtime<'a> {
55 fn push(&mut self, future: impl Future<Output = ()> + 'static) {
57 Runtime::push_boxed(self, Box::pin(future))
58 }
59 fn push_boxed(&mut self, future: BoxFuture<'static, ()>);
61
62 fn spawn(&'a mut self, future: impl Future<Output = ()> + 'static) -> SpawnedFuture<'a> {
65 Runtime::spawn_boxed(self, Box::pin(future))
66 }
67 fn spawn_boxed(&'a mut self, future: BoxFuture<'static, ()>) -> SpawnedFuture<'a>;
70
71 fn sleep<'b>(&'a self, duration: Duration) -> BoxFuture<'b, ()>;
73 fn sleep_ms<'b>(&'a self, amount: u64) -> BoxFuture<'b, ()> {
75 self.sleep(Duration::from_millis(amount))
76 }
77
78 fn stop(&mut self) -> Stop;
80}
81
82pub struct RuntimeWrapper<'a>(pub(crate) &'a mut dyn InternalRuntime);
84
85pub struct OwnedRuntime<'a>(RuntimeWrapper<'a>, pub(crate) Box<dyn InternalRuntime + 'a>);
87
88impl<'a> Deref for OwnedRuntime<'a> {
89 type Target = RuntimeWrapper<'a>;
90
91 fn deref(&self) -> &Self::Target {
92 &self.0
93 }
94}
95
96impl<'a> Runtime<'a> for RuntimeWrapper<'a> {
97 fn push_boxed(&mut self, future: BoxFuture<'static, ()>) {
98 InternalRuntime::push_boxed(self.0, future);
99 }
100
101 fn spawn_boxed(&'a mut self, future: BoxFuture<'static, ()>) -> SpawnedFuture<'a> {
102 SpawnedFuture(InternalRuntime::push_boxed(self.0, future), self.0)
103 }
104
105 fn sleep<'b>(&'a self, duration: Duration) -> BoxFuture<'b, ()> {
106 InternalRuntime::sleep(self.0, duration)
107 }
108
109 fn stop(&mut self) -> Stop {
110 InternalRuntime::stop(self.0)
111 }
112}
113
114impl<'a, T: InternalRuntime + Sized> Runtime<'a> for T {
115 fn push_boxed(&mut self, future: BoxFuture<'static, ()>) {
116 InternalRuntime::push_boxed(self, future);
117 }
118
119 fn spawn_boxed(&'a mut self, future: BoxFuture<'static, ()>) -> SpawnedFuture<'a> {
120 SpawnedFuture(InternalRuntime::push_boxed(self, future), self)
121 }
122
123 fn sleep<'b>(&'a self, duration: Duration) -> BoxFuture<'b, ()> {
124 InternalRuntime::sleep(self, duration)
125 }
126
127 fn stop(&mut self) -> Stop {
128 InternalRuntime::stop(self)
129 }
130}
131
132pub trait StartableRuntime<'a>: InternalRuntime + Sized + 'a {
134 fn new() -> OwnedRuntime<'a> {
136 let mut bx = Box::new(Self::construct());
137 OwnedRuntime(
138 RuntimeWrapper(unsafe { (bx.as_mut() as *mut dyn InternalRuntime).as_mut().unwrap() }),
139 bx,
140 )
141 }
142
143 fn construct() -> Self;
146}
147
148impl<'a, T: InternalRuntime + Sized + 'a> StartableRuntime<'a> for T
149where
150 T: Default,
151{
152 fn construct() -> Self {
153 Self::default()
154 }
155}