flaque 0.2.0

A fast, concurrent, lock-free, and sometimes wait-free, pool implementation
Documentation
// Copyright 2026 Ivan Enderlin <ivan@mnt.io>. Licensed under the EUPL, version
// 1.2. See the `LICENSE` file.

use std::convert::Infallible;

#[cfg(doc)]
use super::Pool;

/// A “marker” to represent a [`Pool`] that uses a synchronous object builder
/// (i.e. [`SyncBuilder`]).
///
/// This is not to be used by users. This is computed by [`Pool::new`].
#[repr(transparent)]
pub struct Sync<B>(pub(super) B);

/// A “marker” to represent a [`Pool`] that uses an asynchronous object builder
/// (i.e. [`AsyncBuilder`]).
///
/// This is not to be used by users. This is computed by
/// [`Pool::new_with_async_builder`].
#[repr(transparent)]
pub struct Async<B>(pub(super) B);

/// A trait representing any kind of synchronous builders, used to produce new
/// object for the [`Pool`].
///
/// See:
///
/// - [`Pool::new`] to build a `Pool` with a synchronous object builder,
/// - [`AsyncBuilder`] to get the asynchronous flavour of it.
pub trait SyncBuilder<T> {
    type Error;

    /// Possibly build a new object `T` for the [`Pool`].
    fn build_object(&self) -> Result<T, Self::Error>;
}

/// A trait representing any kind of asynchronous builders, used to produce new
/// object for the [`Pool`].
///
/// See:
///
/// - [`Pool::new_with_async_builder`] to build a `Pool` with an asynchronous
///   object builder,
/// - [`SyncBuilder`] to get the synchronous flavour of it.
pub trait AsyncBuilder<T> {
    type Error;

    /// Possibly build a new object `T` for the [`Pool`].
    fn build_object(&self) -> impl Future<Output = Result<T, Self::Error>>;
}

impl<T, B> SyncBuilder<T> for Sync<B>
where
    B: SyncBuilder<T>,
{
    type Error = B::Error;

    fn build_object(&self) -> Result<T, Self::Error> {
        self.0.build_object()
    }
}

impl<T, B> AsyncBuilder<T> for Async<B>
where
    B: AsyncBuilder<T>,
{
    type Error = B::Error;

    fn build_object(&self) -> impl Future<Output = Result<T, Self::Error>> {
        self.0.build_object()
    }
}

impl<T, F, R> SyncBuilder<T> for F
where
    F: Fn() -> R,
    R: IntoResult<T>,
{
    type Error = <R as IntoResult<T>>::Error;

    fn build_object(&self) -> Result<T, Self::Error> {
        (self)().into_result()
    }
}

impl<T, F, R> AsyncBuilder<T> for F
where
    F: AsyncFn() -> R,
    R: IntoResult<T>,
{
    type Error = <R as IntoResult<T>>::Error;

    async fn build_object(&self) -> Result<T, Self::Error> {
        (self)().await.into_result()
    }
}

/// A trait to transform any `T` into a `Result<T, Self::Error>`.
///
/// This is used by the [`SyncBuilder`] and [`AsyncBuilder`].
pub trait IntoResult<T> {
    type Error;

    /// Transform `self` into a `Result<T, E>`.
    fn into_result(self) -> Result<T, Self::Error>;
}

impl<T> IntoResult<T> for T {
    type Error = Infallible;

    fn into_result(self) -> Result<T, Self::Error> {
        Ok(self)
    }
}

impl<T, E> IntoResult<T> for Result<T, E> {
    type Error = E;

    fn into_result(self) -> Result<T, E> {
        self
    }
}