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}