object-rainbow 0.0.0-a.72

distributed object model
Documentation
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)
}