Skip to main content

injectium_macro/
lib.rs

1//! Procedural macros for Injectium.
2//!
3//! This crate provides:
4//!
5//! - `#[derive(Injectable)]` – implements the [`Injectable`] trait for your
6//!   structs, automatically pulling each field from the container.
7
8mod inject;
9
10use proc_macro::TokenStream;
11use syn::{DeriveInput, parse_macro_input};
12
13/// Derives an implementation of the `injectium::Injectable` trait.
14///
15/// When applied to a named struct, this macro generates:
16///
17/// 1. An implementation of `from_container(&Container) -> Self` that resolves
18///    each field from the container using `container.get::<T>()`.
19/// 2. An implementation of `try_from_container(&Container) -> Option<Self>`
20///    that uses `container.try_get::<T>()` for graceful missing-dependency
21///    handling.
22/// 3. A `injectium::declare_dependency!` call for each field type, enabling
23///    `Container::validate` to check all dependencies at startup.
24///
25/// # Requirements
26///
27/// - The struct must be a named struct (not a tuple struct or enum).
28/// - All field types must be `'static`.
29///
30/// # Example
31///
32/// ```ignore
33/// use injectium::Injectable;
34/// use std::sync::Arc;
35///
36/// #[derive(Clone)]
37/// struct Database {
38///     conn: Arc<Connection>,
39/// }
40///
41/// #[derive(Injectable)]
42/// struct Service {
43///     db: Database,
44/// }
45/// ```
46#[proc_macro_derive(Injectable)]
47pub fn derive_injectable(input: TokenStream) -> TokenStream {
48    let input = parse_macro_input!(input as DeriveInput);
49
50    match inject::expand_inject(input) {
51        Ok(ts) => ts.into(),
52        Err(e) => e.to_compile_error().into(),
53    }
54}