API Reference
toni-macros
Reference for all procedural macros provided by the toni-macros crate.
All macros are re-exported through the toni crate — you don't need to add toni-macros as a direct dependency.
Struct-level macros
#[module]
Defines a module with its dependency graph:
#[module(
imports: [OtherModule, AnotherModule], // modules to import
controllers: [MyController, OtherController], // controllers owned by this module
providers: [MyService, provider_value!("KEY", value)], // providers
exports: [MyService, "KEY"], // what's visible to importers
)]
pub struct MyModule;All fields are optional. An empty module is valid.
#[controller]
Defines an HTTP controller with a base path:
#[controller("/path", pub struct MyController {
#[inject]
service: MyService, // injected from DI
internal: String, // not injected
})]
impl MyController {
pub fn new(service: MyService) -> Self {
Self { service, internal: "default".into() }
}
}#[injectable]
Marks a struct as a DI-managed provider:
#[injectable(pub struct MyService {
#[inject]
dep: OtherService,
state: u32,
})]
impl MyService {
pub fn new(dep: OtherService) -> Self {
Self { dep, state: 0 }
}
}Route macros
Applied to methods inside a #[controller] impl block:
#[get("/path")] // HTTP GET
#[post("/path")] // HTTP POST
#[put("/path")] // HTTP PUT
#[delete("/path")] // HTTP DELETEPath segments with :name are route parameters: #[get("/:id")].
Enhancer application macros
Applied to a controller or method:
#[use_guards(GuardStruct {}, AnotherGuard::new())]
#[use_interceptors(InterceptorStruct {}, LoggingInterceptor::new())]
#[use_pipes(PipeStruct {})]
#[use_error_handlers(ErrorHandlerStruct {})]
#[set_metadata(MyMetadata { key: "value" })]Enhancer marker macros
Mark a #[injectable] struct as implementing an enhancer trait so Toni can detect and register it:
#[guard] // implements Guard
#[interceptor] // implements Interceptor
#[pipe] // implements Pipe
#[middleware] // implements Middleware
#[error_handler] // implements ErrorHandlerProvider macros (used inside providers: [...])
// Static value
provider_value!("TOKEN", expression)
// Sync factory with optional dependencies
provider_factory!("TOKEN", || expression)
provider_factory!("TOKEN", |dep: DepType| expression)
// Async factory
provider_factory!("TOKEN", async |dep: DepType| async_expression)
// Alias — alternate token for existing provider
provider_alias!("NEW_TOKEN", ExistingService)
provider_alias!("NEW_TOKEN", "EXISTING_TOKEN")
// Register type under custom token
provider_token!("CUSTOM_TOKEN", ServiceType)
// Unified macro
provide!(value => "TOKEN" = expr)
provide!(factory => "TOKEN" = || expr)
provide!(alias => "TOKEN" = Original)Lifecycle hook attributes
Used inside impl blocks of providers, controllers, or modules:
#[on_module_init]
async fn hook(&self) { }
#[on_application_bootstrap]
async fn hook(&self) { }
#[on_module_destroy]
async fn hook(&self) { }
#[before_application_shutdown]
async fn hook(&self, signal: Option<String>) { }
#[on_application_shutdown]
async fn hook(&self, signal: Option<String>) { }Field attributes
// In #[injectable] and #[controller] struct definitions:
#[inject] // mark field for DI injection
#[default] // provide a default value (not injected)Config derive macro (from toni-config)
use toni_config::Config;
#[derive(Config, Clone)]
pub struct AppConfig {
#[env("ENV_VAR_NAME")]
pub field: Type,
#[env("ENV_VAR_NAME", default = "value")]
pub optional_field: Type,
#[nested]
pub nested_config: NestedConfig,
}