ducklake 0.0.2

Rust SDK for DuckLake.
Documentation
use std::pin::Pin;

use tokio::sync::OnceCell;

use crate::DucklakeResult;

type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;

pub struct AsyncLazy<T, A = ()> {
    value: OnceCell<T>,
    init: Box<dyn Fn(A) -> BoxFuture<'static, DucklakeResult<T>> + Send + Sync>,
}

impl<T, A> AsyncLazy<T, A> {
    pub fn new<F, Fut>(init: F) -> Self
    where
        F: Fn(A) -> Fut + Send + Sync + 'static,
        Fut: Future<Output = DucklakeResult<T>> + Send + 'static,
    {
        Self {
            value: OnceCell::new(),
            init: Box::new(move |arg| {
                let fut = init(arg);
                Box::pin(fut) as BoxFuture<'static, DucklakeResult<T>>
            }),
        }
    }

    pub async fn get_with_arg(&self, arg: A) -> DucklakeResult<&T> {
        self.value.get_or_try_init(|| (self.init)(arg)).await
    }
}

impl<T> AsyncLazy<T, ()> {
    pub async fn get(&self) -> DucklakeResult<&T> {
        self.get_with_arg(()).await
    }
}