use std::future::Future;
#[async_trait::async_trait]
pub trait Singleton {
type Inner;
fn init_singleton(inner: Self::Inner) -> anyhow::Result<()>;
async fn use_singleton<F, R>(clojure: F) -> R
where
F: for<'c> SingletonFn<'c, Self::Inner, R> + Send,
R: Send;
async fn use_singleton_with_arg<F, A, R>(clojure: F, arg: A) -> R
where
F: for<'c> SingletonFnWithArg<'c, Self::Inner, A, R> + Send,
A: Send,
R: Send;
async fn use_mut_singleton<F, R>(clojure: F) -> R
where
F: for<'c> SingletonFnMut<'c, Self::Inner, R> + Send,
R: Send;
async fn use_mut_singleton_with_arg<F, A, R>(clojure: F, arg: A) -> R
where
F: for<'c> SingletonFnMutWithArg<'c, Self::Inner, A, R> + Send,
A: Send,
R: Send;
}
pub trait SingletonFn<'i, I, R>
where
R: Send,
{
type SingletonResult: Future<Output = R> + Send;
fn call_once(self, inner: &'i I) -> Self::SingletonResult;
}
impl<'i, I, R, F, FR> SingletonFn<'i, I, R> for F
where
I: 'i,
F: FnOnce(&'i I) -> FR,
FR: Future<Output = R> + Send + 'i,
R: Send,
{
type SingletonResult = FR;
fn call_once(self, inner: &'i I) -> Self::SingletonResult {
self(inner)
}
}
pub trait SingletonFnWithArg<'i, I, A, R>
where
A: Send,
R: Send,
{
type SingletonResult: Future<Output = R> + Send;
fn call_once(self, inner: &'i I, arg: A) -> Self::SingletonResult;
}
impl<'i, A, I, R, F, FR> SingletonFnWithArg<'i, I, A, R> for F
where
I: 'i,
F: FnOnce(&'i I, A) -> FR,
FR: Future<Output = R> + Send + 'i,
A: Send,
R: Send,
{
type SingletonResult = FR;
fn call_once(self, inner: &'i I, arg: A) -> Self::SingletonResult {
self(inner, arg)
}
}
pub trait SingletonFnMut<'i, I, R>
where
R: Send,
{
type SingletonResult: Future<Output = R> + Send;
fn call_once(self, inner: &'i mut I) -> Self::SingletonResult;
}
impl<'i, I, R, F, FR> SingletonFnMut<'i, I, R> for F
where
I: 'i,
F: FnMut(&'i mut I) -> FR,
FR: Future<Output = R> + Send + 'i,
R: Send,
{
type SingletonResult = FR;
fn call_once(mut self, inner: &'i mut I) -> Self::SingletonResult {
self(inner)
}
}
pub trait SingletonFnMutWithArg<'i, I, A, R>
where
A: Send,
R: Send,
{
type SingletonResult: Future<Output = R> + Send;
fn call_once(self, inner: &'i mut I, arg: A) -> Self::SingletonResult;
}
impl<'i, A, I, R, F, FR> SingletonFnMutWithArg<'i, I, A, R> for F
where
I: 'i,
F: FnOnce(&'i mut I, A) -> FR,
FR: Future<Output = R> + Send + 'i,
A: Send,
R: Send,
{
type SingletonResult = FR;
fn call_once(self, inner: &'i mut I, arg: A) -> Self::SingletonResult {
self(inner, arg)
}
}