Skip to main content

object_rainbow/
fn_fetch.rs

1use crate::*;
2
3pub struct FnFetch<F> {
4    fetch: F,
5}
6
7pub trait FetchFn: Send + Sync {
8    type T;
9    fn fetch(&self) -> impl Send + Future<Output = Result<Self::T>>;
10}
11
12impl<F: Send + Sync + Fn() -> Fut, Fut: Send + Future<Output = Result<T>>, T> FetchFn for F {
13    type T = T;
14
15    fn fetch(&self) -> impl Send + Future<Output = Result<Self::T>> {
16        self()
17    }
18}
19
20impl<F: FetchFn> FnFetch<F> {
21    pub fn new(fetch: F) -> Self {
22        Self { fetch }
23    }
24
25    pub async fn fetch(&self) -> Result<F::T> {
26        self.fetch.fetch().await
27    }
28
29    async fn fetch_node(&self) -> Result<Node<F::T>>
30    where
31        F::T: Traversible,
32    {
33        let object = self.fetch().await?;
34        let resolve = object.to_resolve();
35        Ok((object, resolve))
36    }
37}
38
39impl<F: FetchFn<T: Traversible>> FetchBytes for FnFetch<F> {
40    fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
41        Box::pin(async move {
42            let (object, resolve) = self.fetch_node().await?;
43            let data = object.output();
44            Ok((data, resolve))
45        })
46    }
47
48    fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
49        Box::pin(async move { Ok(self.fetch().await?.output()) })
50    }
51}
52
53impl<F: FetchFn<T: Traversible>> Fetch for FnFetch<F> {
54    type T = F::T;
55
56    fn fetch_full(&'_ self) -> FailFuture<'_, Node<Self::T>> {
57        Box::pin(async move { self.fetch_node().await })
58    }
59
60    fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
61        Box::pin(async move { self.fetch().await })
62    }
63}
64
65pub trait ClosureFn<'a, Closure: 'a>: Send + Sync + Fn(&'a Closure) -> Self::Fut {
66    type T;
67    type Fut: Send + Future<Output = Result<Self::T>>;
68    fn fetch(&'a self, closure: &'a Closure) -> Self::Fut;
69}
70
71impl<
72    'a,
73    Closure: 'a,
74    F: Send + Sync + Fn(&'a Closure) -> Fut,
75    Fut: Send + Future<Output = Result<T>>,
76    T,
77> ClosureFn<'a, Closure> for F
78{
79    type T = T;
80    type Fut = Fut;
81
82    fn fetch(&'a self, closure: &'a Closure) -> Self::Fut {
83        self(closure)
84    }
85}
86
87pub trait ClosureFetch<Closure>: Send + Sync {
88    type T;
89    fn fetch(&self, closure: &Closure) -> impl Send + Future<Output = Result<Self::T>>;
90}
91
92impl<Closure: Send + Sync, F: for<'a> ClosureFn<'a, Closure, T = T>, T> ClosureFetch<Closure>
93    for F
94{
95    type T = T;
96
97    async fn fetch(&self, closure: &Closure) -> Result<Self::T> {
98        self.fetch(closure).await
99    }
100}
101
102impl<Closure: Send + Sync, F: ClosureFetch<Closure>> FetchFn for (Closure, F) {
103    type T = F::T;
104
105    fn fetch(&self) -> impl Send + Future<Output = Result<Self::T>> {
106        self.1.fetch(&self.0)
107    }
108}
109
110pub fn closure_fetch<
111    Closure: Send + Sync,
112    F: ClosureFetch<Closure> + AsyncFn(&Closure) -> Result<F::T>,
113>(
114    closure: Closure,
115    f: F,
116) -> (Closure, F) {
117    (closure, f)
118}