doctest_support/
basic_delay.rs

1use std::future::Future;
2
3use crux_core::{command::RequestBuilder, Command, Request};
4use serde::{Deserialize, Serialize};
5
6// ANCHOR: operation
7#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
8pub struct DelayOperation {
9    millis: usize,
10}
11// ANCHOR_END: operation
12
13// ANCHOR: operation_impl
14impl crux_core::capability::Operation for DelayOperation {
15    type Output = ();
16}
17// ANCHOR_END: operation_impl
18
19// ANCHOR: functions
20/// Request a delay for the specified number of milliseconds.
21#[must_use]
22pub fn milliseconds<Effect, Event>(
23    millis: usize,
24) -> RequestBuilder<Effect, Event, impl Future<Output = ()>>
25where
26    Effect: Send + From<Request<DelayOperation>> + 'static,
27    Event: Send + 'static,
28{
29    Command::request_from_shell(DelayOperation { millis })
30}
31// ANCHOR_END: functions
32
33// ANCHOR: tests
34#[cfg(test)]
35mod tests {
36    use crux_core::macros::effect;
37
38    use super::*;
39
40    #[effect]
41    pub enum Effect {
42        Delay(DelayOperation),
43    }
44
45    enum Event {
46        TimeUp(()),
47    }
48
49    #[test]
50    fn test_delay() {
51        let delay = 100;
52
53        let mut cmd = milliseconds(delay).then_send(Event::TimeUp);
54
55        let effect = cmd.expect_one_effect();
56        let Effect::Delay(mut request) = effect;
57
58        assert_eq!(request.operation, DelayOperation { millis: delay });
59
60        request.resolve(()).unwrap();
61
62        let event = cmd.events().next().unwrap();
63        assert!(matches!(event, Event::TimeUp(())));
64
65        assert!(cmd.is_done());
66    }
67}
68// ANCHOR_END: tests