Skip to main content

doctest_support/
basic_delay.rs

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