use std::{
future::{ready, Future, Ready},
ops::Deref,
};
use super::FromContext;
use crate::BoxError;
mod mode {
pub enum Once {}
pub enum Repeat {}
}
#[doc(hidden)]
pub struct Exclusive<'c, C> {
context: &'c C,
}
impl<'c, C> Exclusive<'c, C> {
pub(crate) fn new(context: &'c C) -> Self {
Self { context }
}
pub fn get(&self) -> &'c C {
self.context
}
}
impl<C> Deref for Exclusive<'_, C> {
type Target = C;
fn deref(&self) -> &Self::Target {
self.get()
}
}
pub trait FromContextOnce<C, M = mode::Once>: Sized {
type Error: Into<BoxError>;
type Future<'c>: Future<Output = Result<Self, Self::Error>> + 'c
where
C: 'c;
fn from_context_once(context: Exclusive<C>) -> Self::Future<'_>;
}
impl<C, T> FromContextOnce<C, mode::Repeat> for T
where
for<'c> T: FromContext<C> + 'c,
{
type Error = T::Error;
type Future<'c>
= Ready<Result<Self, Self::Error>>
where
C: 'c,
Self: 'c;
fn from_context_once(context: Exclusive<C>) -> Self::Future<'_> {
ready(T::from_context(&context))
}
}