use crate::*;
pub struct FnFetch<F> {
fetch: F,
}
pub trait FetchFn: Send + Sync {
type T;
fn fetch(&self) -> impl Send + Future<Output = Result<Self::T>>;
}
impl<F: Send + Sync + Fn() -> Fut, Fut: Send + Future<Output = Result<T>>, T> FetchFn for F {
type T = T;
fn fetch(&self) -> impl Send + Future<Output = Result<Self::T>> {
self()
}
}
impl<F: FetchFn> FnFetch<F> {
pub fn new(fetch: F) -> Self {
Self { fetch }
}
pub async fn fetch(&self) -> Result<F::T> {
self.fetch.fetch().await
}
}
impl<F: FetchFn<T: Traversible>> FetchBytes for FnFetch<F> {
fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
Box::pin(async move { Ok(self.fetch().await?.byte_node()) })
}
fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
Box::pin(async move { Ok(self.fetch().await?.vec()) })
}
}
impl<F: FetchFn<T: Traversible>> Fetch for FnFetch<F> {
type T = F::T;
fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
Box::pin(async move { self.fetch().await })
}
}
pub trait ClosureFn<'a, Closure: 'a>: Send + Sync + Fn(&'a Closure) -> Self::Fut {
type T;
type Fut: Send + Future<Output = Result<Self::T>>;
fn fetch(&'a self, closure: &'a Closure) -> Self::Fut;
}
impl<
'a,
Closure: 'a,
F: Send + Sync + Fn(&'a Closure) -> Fut,
Fut: Send + Future<Output = Result<T>>,
T,
> ClosureFn<'a, Closure> for F
{
type T = T;
type Fut = Fut;
fn fetch(&'a self, closure: &'a Closure) -> Self::Fut {
self(closure)
}
}
pub trait ClosureFetch<Closure>: Send + Sync {
type T;
fn fetch(&self, closure: &Closure) -> impl Send + Future<Output = Result<Self::T>>;
}
impl<Closure: Send + Sync, F: for<'a> ClosureFn<'a, Closure, T = T>, T> ClosureFetch<Closure>
for F
{
type T = T;
async fn fetch(&self, closure: &Closure) -> Result<Self::T> {
self.fetch(closure).await
}
}
impl<Closure: Send + Sync, F: ClosureFetch<Closure>> FetchFn for (Closure, F) {
type T = F::T;
fn fetch(&self) -> impl Send + Future<Output = Result<Self::T>> {
self.1.fetch(&self.0)
}
}
pub fn closure_fetch<
Closure: Send + Sync,
F: ClosureFetch<Closure> + AsyncFn(&Closure) -> Result<F::T>,
>(
closure: Closure,
f: F,
) -> (Closure, F) {
(closure, f)
}