sequent_repl/commands/
next.rs

1//! Stepping through the next event.
2
3use std::borrow::Cow;
4use std::marker::PhantomData;
5use sequent::SimulationError;
6use revolver::command::{ApplyCommandError, ApplyOutcome, Command, Description, NamedCommandParser, ParseCommandError};
7use revolver::looper::Looper;
8use revolver::terminal::Terminal;
9use crate::Context;
10
11/// Command to step through the next event in the timeline. Upon completion, the current simulation state
12/// will reflect the sequential application of all events up to and including the upcoming event, and
13/// the cursor location will advance to the subsequent event (one after the upcoming event).
14pub struct Next<S, C> {
15    __phantom_data: PhantomData<(S, C)>
16}
17
18impl<S, C> Default for Next<S, C> {
19    fn default() -> Self {
20        Self {
21            __phantom_data: PhantomData::default()
22        }
23    }
24}
25
26impl<S, C: Context<State = S>, T: Terminal> Command<T> for Next<S, C> {
27    type Context = C;
28    type Error = SimulationError<S>;
29
30    fn apply(&mut self, looper: &mut Looper<C, SimulationError<S>, T>) -> Result<ApplyOutcome, ApplyCommandError<SimulationError<S>>> {
31        let (terminal, _, context) = looper.split();
32        context.sim().step().map_err(ApplyCommandError::Application)?;
33        context.print_state(terminal)?;
34        Ok(ApplyOutcome::Applied)
35    }
36}
37
38/// Parser for [`Next`].
39pub struct Parser<S, C> {
40    __phantom_data: PhantomData<(S, C)>
41}
42
43impl<S, C> Default for Parser<S, C> {
44    fn default() -> Self {
45        Self {
46            __phantom_data: PhantomData::default()
47        }
48    }
49}
50
51impl<S: 'static, C: Context<State = S> + 'static, T: Terminal> NamedCommandParser<T> for Parser<S, C> {
52    type Context = C;
53    type Error = SimulationError<S>;
54
55    fn parse(&self, s: &str) -> Result<Box<dyn Command<T, Context = C, Error = SimulationError<S>>>, ParseCommandError> {
56        self.parse_no_args(s, Next::default)
57    }
58
59    fn shorthand(&self) -> Option<Cow<'static, str>> {
60        Some("n".into())
61    }
62
63    fn name(&self) -> Cow<'static, str> {
64        "next".into()
65    }
66    
67    fn description(&self) -> Description {
68        Description {
69            purpose: "Steps through the next event in the timeline.".into(),
70            usage: Cow::default(),
71            examples: Vec::default()
72        }
73    }
74}
75
76#[cfg(test)]
77mod tests;