he_di 0.2.1

Dependency Inversion / Dependency Injection / Inversion of control container for Rust
Documentation
extern crate he_di;
#[macro_use] extern crate he_di_derive;

trait Foo { fn foo(&self); }
trait FooInvalid { fn foo(&self); }
trait FooDuplicate { fn foo(&self); }

#[derive(Component)]
#[interface(Foo)]
struct FooImpl;

#[derive(Component)]
#[interface(FooInvalid)]
struct FooInvalidImpl;

#[derive(Component)]
#[interface(FooDuplicate)]
struct FooDuplicateImpl1;

#[derive(Component)]
#[interface(FooDuplicate)]
struct FooDuplicateImpl2;

impl Foo for FooImpl { fn foo(&self) { } }
impl FooInvalid for FooInvalidImpl { fn foo(&self) { } }
impl FooDuplicate for FooDuplicateImpl1 { fn foo(&self) { } }
impl FooDuplicate for FooDuplicateImpl2 { fn foo(&self) { } }

#[test]
fn container_builder_doc_example() {
    let mut builder = he_di::ContainerBuilder::new();
    // Valid registration
    builder.register::<FooImpl>()
        .as_type::<Foo>();

    let container = builder.build();
    assert!(container.is_ok());
    let foo = container.unwrap().resolve::<Foo>();
    assert!(foo.is_ok());
    
    // Invalid registration => 'as_type()' wasn't called
    let mut builder = he_di::ContainerBuilder::new();
    builder.register::<FooInvalidImpl>();

    let container = builder.build();
    assert!(container.is_err());

    if let he_di::Error::RegistrationError(he_di::container::ValidatorError::EmptyValue(msg)) = container.unwrap_err() {
        let expected_msg = "invalid entry: Component 'FooInvalidImpl' hasn't been registered to a type (use `as_trait()` in the registration chain)".to_string();
        assert_eq!(msg, expected_msg);
    } else {
        panic!("invalid state > container should be a RegistrationError(EmptyValue)");
    }

    // Invalid registration
    let mut builder = he_di::ContainerBuilder::new();
    builder.register::<FooDuplicateImpl1>()
        .as_type::<FooDuplicate>();
    builder.register::<FooDuplicateImpl2>()
        .as_type::<FooDuplicate>();

    let container = builder.build();
    assert!(container.is_err());

    if let he_di::Error::RegistrationError(he_di::container::ValidatorError::MultipleErrors(errs)) = container.unwrap_err() {
        assert_eq!(errs.len(), 2);

        let expected_err = he_di::container::ValidatorError::IllegalValue("duplicate entry: multiple components are registered to type FooDuplicate > FooDuplicateImpl1".to_string());
        assert!(errs.iter().find(|err| err == &&expected_err).is_some());

        let expected_err = he_di::container::ValidatorError::IllegalValue("duplicate entry: multiple components are registered to type FooDuplicate > FooDuplicateImpl2".to_string());
        assert!(errs.iter().find(|err| err == &&expected_err).is_some());
    } else {
        panic!("invalid state > container should be a RegistrationError(MultipleErrors([IllegalValue,IllegalValue]))");
    }
}