Skip to content

Instantly share code, notes, and snippets.

@demurgos
Created December 2, 2020 22:13
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/dc74e63cbc516e5adb825d6719f6c1a6 to your computer and use it in GitHub Desktop.
Save demurgos/dc74e63cbc516e5adb825d6719f6c1a6 to your computer and use it in GitHub Desktop.
use std::sync::Arc;
use crate::core::{Provider, 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 {}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Clone)]
pub struct ApiClock<T: ApiLike> {
parent: T,
extra: Arc<dyn Clock + Sync + Send>
}
impl<T: ApiLike> ApiLike for ApiClock<T> {}
impl<T: ApiLike> Provider<Arc<dyn Clock + Sync + Send>> for ApiClock<T> {
fn get(&self) -> Arc<dyn Clock + Sync + Send> {
Arc::clone(&self.extra)
}
}
impl<T: ApiLike + Provider<Arc<dyn SimpleUserService + Sync + Send>>> Provider<Arc<dyn SimpleUserService + Sync + Send>> for ApiClock<T> {
fn get(&self) -> Arc<dyn SimpleUserService + Sync + Send> {
self.parent.get()
}
}
impl<T: ApiLike + Provider<Arc<dyn UuidGenerator + Sync + Send>>> Provider<Arc<dyn UuidGenerator + Sync + Send>> for ApiClock<T> {
fn get(&self) -> Arc<dyn UuidGenerator + Sync + Send> {
self.parent.get()
}
}
#[derive(Clone)]
pub struct ApiSimpleUser<T: ApiLike> {
parent: T,
extra: Arc<dyn SimpleUserService + Sync + Send>
}
impl<T: ApiLike> ApiLike for ApiSimpleUser<T> {}
impl<T: ApiLike + Provider<Arc<dyn Clock + Sync + Send>>> Provider<Arc<dyn Clock + Sync + Send>> for ApiSimpleUser<T> {
fn get(&self) -> Arc<dyn Clock + Sync + Send> {
self.parent.get()
}
}
impl<T: ApiLike> Provider<Arc<dyn SimpleUserService + Sync + Send>> for ApiSimpleUser<T> {
fn get(&self) -> Arc<dyn SimpleUserService + Sync + Send> {
Arc::clone(&self.extra)
}
}
impl<T: ApiLike + Provider<Arc<dyn UuidGenerator + Sync + Send>>> Provider<Arc<dyn UuidGenerator + Sync + Send>> for ApiSimpleUser<T> {
fn get(&self) -> Arc<dyn UuidGenerator + Sync + Send> {
self.parent.get()
}
}
#[derive(Clone)]
pub struct ApiUuidGenerator<T: ApiLike> {
parent: T,
extra: Arc<dyn UuidGenerator + Sync + Send>
}
impl<T: ApiLike> ApiLike for ApiUuidGenerator<T> {}
impl<T: ApiLike + Provider<Arc<dyn Clock + Sync + Send>>> Provider<Arc<dyn Clock + Sync + Send>> for ApiUuidGenerator<T> {
fn get(&self) -> Arc<dyn Clock + Sync + Send> {
self.parent.get()
}
}
impl<T: ApiLike + Provider<Arc<dyn SimpleUserService + Sync + Send>>> Provider<Arc<dyn SimpleUserService + Sync + Send>> for ApiUuidGenerator<T> {
fn get(&self) -> Arc<dyn SimpleUserService + Sync + Send> {
self.parent.get()
}
}
impl<T: ApiLike> Provider<Arc<dyn UuidGenerator + Sync + Send>> for ApiUuidGenerator<T> {
fn get(&self) -> Arc<dyn UuidGenerator + Sync + Send> {
Arc::clone(&self.extra)
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pub trait WithClock {
fn with_clock(&self, extra: Arc<dyn Clock + Sync + Send>) -> ApiClock<Self> where Self: ApiLike;
}
impl<T: ApiLike> WithClock for T {
fn with_clock(&self, extra: Arc<dyn Clock + Sync + Send>) -> ApiClock<Self> where Self: ApiLike {
ApiClock { parent: self.clone(), extra }
}
}
pub trait WithSimpleUser {
fn with_simple_user(&self, extra: Arc<dyn SimpleUserService + Sync + Send>) -> ApiSimpleUser<Self> where Self: ApiLike;
}
impl<T: ApiLike> WithSimpleUser for T {
fn with_simple_user(&self, extra: Arc<dyn SimpleUserService + Sync + Send>) -> ApiSimpleUser<Self> where Self: ApiLike {
ApiSimpleUser { parent: self.clone(), extra }
}
}
pub trait WithUuidGenerator {
fn with_uuid_generator(&self, extra: Arc<dyn UuidGenerator + Sync + Send>) -> ApiUuidGenerator<Self> where Self: ApiLike;
}
impl<T: ApiLike> WithUuidGenerator for T {
fn with_uuid_generator(&self, extra: Arc<dyn UuidGenerator + Sync + Send>) -> ApiUuidGenerator<Self> where Self: ApiLike {
ApiUuidGenerator { parent: self.clone(), extra }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment