Skip to main content

sim_lib_control/
async.rs

1use sim_kernel::Ref;
2
3/// Outcome of polling an [`AsyncTask`]: not yet complete, or a ready result.
4#[derive(Clone, Debug, PartialEq, Eq)]
5pub enum AsyncPoll {
6    /// The task has not yet reached its ready point and must be polled again.
7    Pending,
8    /// The task completed, carrying its result [`Ref`].
9    Ready(Ref),
10}
11
12/// A deterministic async task that resolves after a fixed number of polls.
13///
14/// The simplest control organ in this crate: it models the poll-to-completion
15/// surface of asynchronous behavior without a real executor, so the
16/// control-policy contracts can be exercised deterministically.
17#[derive(Clone, Debug, PartialEq, Eq)]
18pub struct AsyncTask {
19    result: Ref,
20    pending_polls: usize,
21    polls: usize,
22}
23
24impl AsyncTask {
25    /// Builds a task that reports [`AsyncPoll::Pending`] for `pending_polls`
26    /// polls, then yields `result`.
27    pub fn ready_after(pending_polls: usize, result: Ref) -> Self {
28        Self {
29            result,
30            pending_polls,
31            polls: 0,
32        }
33    }
34
35    /// Advances the task one step, returning [`AsyncPoll::Pending`] until the
36    /// pending count is exhausted and [`AsyncPoll::Ready`] thereafter.
37    pub fn poll(&mut self) -> AsyncPoll {
38        if self.polls < self.pending_polls {
39            self.polls += 1;
40            return AsyncPoll::Pending;
41        }
42        AsyncPoll::Ready(self.result.clone())
43    }
44}