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}