tabs/
sequence.rs

1use crate::Task;
2use tokio::{self, spawn, task::JoinHandle};
3
4pub struct Sequence {
5    fs_reversed: Vec<Box<dyn FnMut() + Send>>,
6}
7
8impl Sequence {
9    pub fn new(fs: impl Into<Vec<Box<dyn FnMut() + Send>>>) -> Self {
10        let mut fs = fs.into();
11        fs.reverse();
12        Self { fs_reversed: fs }
13    }
14}
15
16pub struct SequenceStarted {
17    pub h: JoinHandle<()>,
18}
19
20impl Task for Sequence {
21    type Started = SequenceStarted;
22    fn start(mut self) -> Self::Started {
23        let h = spawn(async move {
24            while let Some(mut f) = self.fs_reversed.pop() {
25                spawn(async move {
26                    (f)();
27                })
28                .await
29                .unwrap();
30            }
31        });
32        SequenceStarted { h }
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use std::sync::{Arc, RwLock};
40
41    #[test]
42    fn can_instantiate_sequence() {
43        let fs: Vec<Box<dyn FnMut() + Send>> = vec![
44            Box::new(|| {
45                println!("hello");
46            }),
47            Box::new(|| {
48                println!("world");
49            }),
50        ];
51        let _task = Sequence::new(fs);
52    }
53
54    #[tokio::test]
55    async fn can_start_sequence() {
56        let s = Arc::new(RwLock::new("".to_owned()));
57        let s2 = s.clone();
58        let s3 = s.clone();
59        let fs: Vec<Box<dyn FnMut() + Send>> = vec![
60            Box::new(move || {
61                s2.write().unwrap().push_str("hello");
62            }),
63            Box::new(move || {
64                s3.write().unwrap().push_str(" world");
65            }),
66        ];
67        Sequence::new(fs).start().h.await.unwrap();
68        let s = s.read().unwrap();
69        assert_eq!(s.as_str(), "hello world");
70    }
71}