1use futures::Future;
2use std::{ops::Range, pin::Pin};
3
4pub trait Factory {
5 type Item;
6 type Output: IntoIterator<Item = Self::Item>;
7 type Future: Future<Output = Self::Output>;
8
9 fn make(&self, range: Range<usize>, is_rev: bool) -> Self::Future;
10}
11
12pub fn from_fn<F, Fut, V>(f: F) -> FromFn<F>
13where
14 F: Fn(usize) -> Fut + Clone + 'static,
15 Fut: Future<Output = V> + 'static,
16 V: 'static,
17{
18 FromFn { f }
19}
20
21#[derive(Clone, Copy)]
22pub struct FromFn<F> {
23 f: F,
24}
25
26impl<F, Fut, V> Factory for FromFn<F>
27where
28 F: Fn(usize) -> Fut + Clone + 'static,
29 Fut: Future<Output = V> + 'static,
30 V: 'static,
31{
32 type Item = V;
33 type Output = std::vec::IntoIter<V>;
34 type Future = Pin<Box<dyn Future<Output = Self::Output>>>;
35
36 fn make(&self, range: Range<usize>, is_rev: bool) -> Self::Future {
37 let f = self.f.clone();
38 Box::pin(async move {
39 let mut values = Vec::new();
40
41 if is_rev {
42 for idx in range.rev() {
43 values.push(f(idx).await)
44 }
45 } else {
46 for idx in range {
47 values.push(f(idx).await)
48 }
49 }
50
51 values.into_iter()
52 })
53 }
54}
55
56pub fn from_range_fn<F, Fut, I, V>(f: F) -> FromRangeFn<F>
57where
58 F: Fn(Range<usize>, bool) -> Fut + Clone + 'static,
59 Fut: Future<Output = I> + 'static,
60 I: IntoIterator<Item = V>,
61 V: 'static,
62{
63 FromRangeFn { f }
64}
65
66#[derive(Clone, Copy)]
67pub struct FromRangeFn<F> {
68 f: F,
69}
70
71impl<F, Fut, I, V> Factory for FromRangeFn<F>
72where
73 F: Fn(Range<usize>, bool) -> Fut + Clone + 'static,
74 Fut: Future<Output = I> + 'static,
75 I: IntoIterator<Item = V>,
76 V: 'static,
77{
78 type Item = V;
79 type Output = I;
80 type Future = Pin<Box<dyn Future<Output = Self::Output>>>;
81
82 fn make(&self, input: Range<usize>, is_rev: bool) -> Self::Future {
83 Box::pin((self.f)(input, is_rev))
84 }
85}