use std::convert::Infallible;
#[cfg(doc)]
use super::Pool;
#[repr(transparent)]
pub struct Sync<B>(pub(super) B);
#[repr(transparent)]
pub struct Async<B>(pub(super) B);
pub trait SyncBuilder<T> {
type Error;
fn build_object(&self) -> Result<T, Self::Error>;
}
pub trait AsyncBuilder<T> {
type Error;
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()
}
}
pub trait IntoResult<T> {
type Error;
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
}
}