Skip to content

Instantly share code, notes, and snippets.

@demurgos
Created December 3, 2020 17:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save demurgos/1c6a8ac1ff93d549e90a34da4f137860 to your computer and use it in GitHub Desktop.
Save demurgos/1c6a8ac1ff93d549e90a34da4f137860 to your computer and use it in GitHub Desktop.
use std::sync::Arc;
use crate::core::{Get, UuidGenerator};
use crate::clock::Clock;
use crate::user::SimpleUserService;
#[derive(Clone)]
pub struct Api(());
pub trait ApiLike: Clone + Sized {}
impl Api {
pub fn new() -> Self {
Self(())
}
}
impl ApiLike for Api {}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pub struct ApiLayer<T: ApiLike, E: Send + Sync + ?Sized> {
parent: T,
extra: Arc<E>
}
impl<T: ApiLike, E: Send + Sync + ?Sized> Clone for ApiLayer<T, E> {
fn clone(&self) -> Self {
Self { parent: self.parent.clone(), extra: Arc::clone(&self.extra)}
}
}
impl<T: ApiLike, E: Send + Sync + ?Sized> ApiLike for ApiLayer<T, E> {}
impl<T: ApiLike + Get<Arc<dyn Clock>>> Get<Arc<dyn Clock>> for ApiLayer<T, dyn SimpleUserService> {
fn get(&self) -> Arc<dyn Clock> {
self.parent.get()
}
}
impl<T: ApiLike + Get<Arc<dyn Clock>>> Get<Arc<dyn Clock>> for ApiLayer<T, dyn UuidGenerator> {
fn get(&self) -> Arc<dyn Clock> {
self.parent.get()
}
}
impl<T: ApiLike + Get<Arc<dyn SimpleUserService>>> Get<Arc<dyn SimpleUserService>> for ApiLayer<T, dyn Clock> {
fn get(&self) -> Arc<dyn SimpleUserService> {
self.parent.get()
}
}
impl<T: ApiLike + Get<Arc<dyn SimpleUserService>>> Get<Arc<dyn SimpleUserService>> for ApiLayer<T, dyn UuidGenerator> {
fn get(&self) -> Arc<dyn SimpleUserService> {
self.parent.get()
}
}
impl<T: ApiLike + Get<Arc<dyn UuidGenerator>>> Get<Arc<dyn UuidGenerator>> for ApiLayer<T, dyn Clock> {
fn get(&self) -> Arc<dyn UuidGenerator> {
self.parent.get()
}
}
impl<T: ApiLike + Get<Arc<dyn UuidGenerator>>> Get<Arc<dyn UuidGenerator>> for ApiLayer<T, dyn SimpleUserService> {
fn get(&self) -> Arc<dyn UuidGenerator> {
self.parent.get()
}
}
impl<T: ApiLike, E: Send + Sync + ?Sized> Get<Arc<E>> for ApiLayer<T, E> {
fn get(&self) -> Arc<E> {
Arc::clone(&self.extra)
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pub trait WithClock {
fn with_clock(&self, extra: Arc<dyn Clock>) -> ApiLayer<Self, dyn Clock> where Self: ApiLike;
}
impl<T: ApiLike> WithClock for T {
fn with_clock(&self, extra: Arc<dyn Clock>) -> ApiLayer<Self, dyn Clock> where Self: ApiLike {
ApiLayer { parent: self.clone(), extra }
}
}
pub trait WithSimpleUser {
fn with_simple_user(&self, extra: Arc<dyn SimpleUserService>) -> ApiLayer<Self, dyn SimpleUserService> where Self: ApiLike;
}
impl<T: ApiLike> WithSimpleUser for T {
fn with_simple_user(&self, extra: Arc<dyn SimpleUserService>) -> ApiLayer<Self, dyn SimpleUserService> where Self: ApiLike {
ApiLayer { parent: self.clone(), extra }
}
}
pub trait WithUuidGenerator {
fn with_uuid_generator(&self, extra: Arc<dyn UuidGenerator>) -> ApiLayer<Self, dyn UuidGenerator> where Self: ApiLike;
}
impl<T: ApiLike> WithUuidGenerator for T {
fn with_uuid_generator(&self, extra: Arc<dyn UuidGenerator>) -> ApiLayer<Self, dyn UuidGenerator> where Self: ApiLike {
ApiLayer { parent: self.clone(), extra }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment