1 unstable release
0.1.0 | Jul 7, 2023 |
---|
#1333 in Procedural macros
36KB
675 lines
dep-inj
A tool for easier dependency injection.
Example
When you write a component(named OddState
here) that need be injected some dependency(named Even
here) from other crates, dep_inj
can help you.
//! odd component implementation
use dep_inj::DepInj;
#[derive(Default, DepInj)]
// to generator `OddProxy`
#[target(OddProxy)]
pub struct OddState {
count: usize,
}
// `OddState` provides `Odd`
impl<Deps> Odd for OddProxy<Deps>
where
// `is_odd` depends on `Even`
Deps: Even
{
fn is_odd(&mut self, n: u64) -> bool {
// `OddProxy` can be deref to `OddState`
self.count += 1;
(n == 1) || self
.prj_ref_mut()
// `OddProxy` can be projected to its dependency `Even`
// where
// ```
// trait Even {
// fn is_even(&mut self, n: u64) -> bool;
// }
// ```
.is_even(n)
}
}
and you can inject the dependency in the top crate:
#[derive(Default)]
struct GlobalState {
odd_state: OddState,
even_state: EvenState,
}
// boilerplate
// `impl AsRef<OddState> for GlobalState`
// `impl AsMut<OddState> for GlobalState`
// `impl AsRef<EvenState> for GlobalState`
// `impl AsMut<EvenState> for GlobalState`
impl Even for GlobalState {
fn is_even(&mut self, n: u64) -> bool {
// inject `GlobalState` which is impl `Odd` for `EvenState` component
EvenProxy::inj_ref_mut(self).is_even(n)
}
}
impl Odd for GlobalState {
fn is_odd(&mut self, n: u64) -> bool {
// inject `GlobalState` which is impl `Even` for `OddState` component
OddProxy::inj_ref_mut(self).is_odd(n)
}
}
fn main() {
let mut state = GlobalState::default();
assert!(state.is_odd(11));
}
See more at Exploring Design Patterns in Rust Inter-Component Interface Invocation
Dependencies
~1.5MB
~36K SLoC