chassis 0.2.0

Compile-time dependency injection framework
Documentation
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;

static INSTANCES: AtomicUsize = AtomicUsize::new(0);

pub struct InstanceCounter {
    instance: usize,
}

impl InstanceCounter {
    pub fn new() -> Self {
        Self {
            instance: INSTANCES.fetch_add(1, Ordering::SeqCst),
        }
    }

    pub fn instance(&self) -> usize {
        self.instance
    }

    pub fn instances() -> usize {
        INSTANCES.load(Ordering::SeqCst)
    }
}

#[derive(Default)]
pub struct TestProvider;

#[chassis::module]
impl TestProvider {
    #[chassis(singleton)]
    pub fn provide_singleton() -> Arc<InstanceCounter> {
        Arc::new(InstanceCounter::new())
    }
}

#[chassis::injector(modules = [TestProvider])]
pub trait TestFactory {
    fn provide_singleton(&self) -> Arc<InstanceCounter>;
}

// TODO: Test multiple singletons
//   Test cyclic singletons

#[test]
fn check() {
    let injector = <dyn TestFactory>::new().unwrap();
    injector.provide_singleton();
    injector.provide_singleton();
    let singleton = injector.provide_singleton();

    assert_eq!(0, singleton.instance());
    assert_eq!(1, InstanceCounter::instances());
}