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}