Skip to content

Instantly share code, notes, and snippets.

@AzureMarker
Created September 28, 2021 01:37
Show Gist options
  • Save AzureMarker/e0afe806723498084f2ad9ff7854ff94 to your computer and use it in GitHub Desktop.
Save AzureMarker/e0afe806723498084f2ad9ff7854ff94 to your computer and use it in GitHub Desktop.
A proof-of-concept for accessing the same shaku component through multiple interfaces.
use shaku::{module, Component, HasComponent, Interface, Module, ModuleBuildContext};
use std::sync::Arc;
trait Fizz: Interface {
fn fizz(&self);
}
trait Buzz: Interface {
fn buzz(&self);
}
trait FizzBuzz: Fizz + Buzz {}
impl<T: Fizz + Buzz> FizzBuzz for T {}
#[derive(Component)]
#[shaku(interface = FizzBuzz)]
struct FooService;
impl Fizz for FooService {
fn fizz(&self) {
println!("Fizz!")
}
}
impl Buzz for FooService {
fn buzz(&self) {
println!("Buzz!")
}
}
struct FooServiceFizz(Arc<dyn FizzBuzz>);
impl Fizz for FooServiceFizz {
fn fizz(&self) {
self.0.fizz()
}
}
impl<M: Module + HasComponent<dyn FizzBuzz>> Component<M> for FooServiceFizz {
type Interface = dyn Fizz;
type Parameters = ();
fn build(context: &mut ModuleBuildContext<M>, _: Self::Parameters) -> Box<Self::Interface> {
Box::new(FooServiceFizz(M::build_component(context)))
}
}
struct FooServiceBuzz(Arc<dyn FizzBuzz>);
impl Buzz for FooServiceBuzz {
fn buzz(&self) {
self.0.buzz()
}
}
impl<M: Module + HasComponent<dyn FizzBuzz>> Component<M> for FooServiceBuzz {
type Interface = dyn Buzz;
type Parameters = ();
fn build(context: &mut ModuleBuildContext<M>, _: Self::Parameters) -> Box<Self::Interface> {
Box::new(FooServiceBuzz(M::build_component(context)))
}
}
module! {
FizzBuzzModule {
components = [FooService, FooServiceFizz, FooServiceBuzz],
providers = []
}
}
fn main() {
let foo_module = FizzBuzzModule::builder().build();
let fizzer: &dyn Fizz = foo_module.resolve_ref();
let buzzer: &dyn Buzz = foo_module.resolve_ref();
fizzer.fizz();
buzzer.buzz();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment