deluge/ops/
chain.rs

1use std::marker::PhantomData;
2use std::sync::Mutex;
3
4use crate::deluge::Deluge;
5use futures::Future;
6
7pub struct Chain<'a, Del1, Del2> {
8    deluge1: Del1,
9    deluge2: Del2,
10    first_exhausted: Mutex<bool>,
11    _lifetime: PhantomData<&'a Del1>,
12}
13
14impl<'a, Del1, Del2> Chain<'a, Del1, Del2>
15where
16    Del1: Deluge,
17    Del2: for<'x> Deluge<Item = Del1::Item, Output<'x> = Del1::Output<'x>>,
18{
19    pub(crate) fn new(deluge1: Del1, deluge2: Del2) -> Self {
20        Self {
21            deluge1,
22            deluge2,
23            first_exhausted: Mutex::new(false),
24            _lifetime: PhantomData,
25        }
26    }
27}
28
29impl<'a, Del1, Del2> Deluge for Chain<'a, Del1, Del2>
30where
31    Del1: Deluge + 'static,
32    Del2: for<'x> Deluge<Item = Del1::Item, Output<'x> = Del1::Output<'x>> + 'static,
33{
34    type Item = Del1::Item;
35    type Output<'x> = impl Future<Output = Option<Self::Item>> + 'x where Self: 'x;
36
37    fn next(&self) -> Option<Self::Output<'_>> {
38        let mut first_exhausted = self.first_exhausted.lock().unwrap();
39
40        let result = if *first_exhausted {
41            self.deluge2.next()
42        } else {
43            match self.deluge1.next() {
44                None => {
45                    *first_exhausted = true;
46                    self.deluge2.next()
47                }
48                otherwise => otherwise,
49            }
50        };
51
52        result.map(|v| async move { v.await })
53    }
54}