Attribute Macro lockjaw::component[][src]

#[component]
Expand description

Annotates a trait that composes the dependency graph and provides items in the graph (An “injector”) .

#[component]
trait MyComponent {
    fn foo(&self) -> crate::Foo;
}

pub fn main() {
    let component: Box<dyn MyComponent> = <dyn MyComponent>::new();
    let foo : Foo = component.foo();
}
epilogue!();

Component methods

Methods on the component trait serves as entry points to the component. They can be used to retrieve bindings inside the component from the outside.

Component methods must take only &self as parameter, and return a type that has bindings in the component. Lockjaw will generate the implementation that returns the binding.

Component builder

For a trait Foo annotated with #[component], a builder method is generated:

impl Foo {
    pub fn build(modules: BUILDER_MODULES) -> Box<dyn Foo>
}

which an instance of the component, with modules in modules installed. BUILDER_MODULES is the annotated struct in the builder_modules metadata.

If the builder_modules metadata is not provided, the modules parameter will be omitted, and the signature becomes pub fn build() -> Box<dyn Foo>

Metadata

Components accept additional metadata in the form of #[component(key=value, key2=value2)].

modules

Optional path or array of path to modules to be installed as fields. Bindings in listed modules will be incorporated into the dependency graph.

These modules must contain no field. Modules with fields must be provided with builder_modules instead.


#[component(modules : [StringModule, UnsignedModule])]
trait MyComponent {
    fn string(&self) -> String;
    fn unsigned(&self) -> u32;
}

builder_modules

Optional path or array of path to a struct annotated by #[builder_modules], which contains modules to be installed as fields. Bindings in listed modules will be incorporated into the dependency graph.

If a module does not contain any field, it can be listed in modules instead.

struct StringModule {
    string : String
}
#[module]
impl StringModule {
    #[provides]
    pub fn provide_string(&self) -> String {
        self.string.clone()
    }
}

#[builder_modules]
pub struct MyBuilderModules {
    module : crate::StringModule,
}
#[component(builder_modules : crate::MyBuilderModules)]
pub trait MyComponent {
    fn string(&self) -> String;
}

fn main() {
    let component = MyComponent::build(MyBuilderModules{
        module: StringModule{
            string: "foo".to_owned()
        }
    });
    
    assert_eq!("foo", component.string());
}
epilogue!();

Method attributes

Methods in a component can have additional attributes that affects their behavior.

Method attributes are nested under #[component], and all nested attributes should be unqualified ( always used as #[attribute] instead of #[lockjaw::attribute]).