1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
//! Procedural macros for Nidus modules, providers, controllers, and routes.
//!
//! The examples in this crate are marked `ignore` because application-facing
//! macro use goes through the `nidus` facade crate, which depends on this
//! proc-macro crate. Adding a reverse doctest dependency here would create a
//! crate cycle. Macro expansion behavior is covered by the facade UI and CLI
//! tests instead.
use TokenStream;
/// Runs an async Nidus entrypoint on a Tokio runtime.
///
/// Use `#[nidus::main]` on the crate's top-level `async fn main()` when an
/// application should use the runtime configuration provided by the Nidus
/// facade. The macro is executable behavior: it rewrites the async function
/// into a synchronous `main` that builds a Tokio runtime and blocks on the
/// original body.
///
/// Basic syntax:
///
/// ```ignore
/// #[nidus::main]
/// async fn main() -> nidus::Result<()> {
/// nidus::prelude::Nidus::bootstrap::<AppModule>()?
/// .with_router(UsersController.into_router())
/// .listen("127.0.0.1:3000")
/// .await
/// }
/// ```
///
/// The annotated function must be async, must be named `main`, and must not
/// already be wrapped in another runtime macro such as `#[tokio::main]`.
/// Returning `Result` is idiomatic because bootstrap, router construction, and
/// server startup can all fail. Common errors are using the macro on a non-async
/// function or applying it to helper functions instead of the binary entrypoint.
/// Declares a Nidus module from a Rust struct.
///
/// `#[module]` is valid on named structs that represent application modules.
/// It is metadata-generating behavior: the macro keeps the struct in place and
/// implements Nidus module metadata so the runtime and CLI can inspect imports,
/// providers, controllers, and exports without runtime reflection.
///
/// Basic syntax:
///
/// ```ignore
/// #[module(
/// imports = [UsersModule],
/// providers = [EmailService],
/// controllers = [HealthController],
/// exports = [EmailService],
/// )]
/// struct AppModule;
/// ```
///
/// The generated module definition composes with `Nidus::bootstrap::<AppModule>()`,
/// graph validation, CLI graph/check commands, and generated starter projects.
/// Module entries are Rust types, not string names, so missing imports or renamed
/// providers are caught by the compiler. Common errors include omitting brackets
/// around metadata lists, placing the macro on enums or tuple structs, and
/// exporting a provider that is not registered by the module or its imports.
/// Declares a struct as an injectable provider.
///
/// `#[injectable]` is valid on named structs. It is metadata-generating
/// behavior: the macro preserves the struct and implements provider registration
/// metadata so modules can list the type in `providers = [...]` and consumers can
/// request it through typed injection primitives.
///
/// Basic syntax:
///
/// ```ignore
/// #[injectable]
/// struct UsersService {
/// repository: nidus::prelude::Inject<UsersRepository>,
/// }
/// ```
///
/// Injectable providers compose with `Inject<T>`, `Optional<T>`, `Lazy<T>`,
/// `Factory<T>`, and request-scoped providers exposed by the Nidus core. The
/// macro is intentionally explicit: constructor behavior is not hidden behind
/// runtime string lookup. Common errors are applying it to tuple structs,
/// unsupported generic/lifetime shapes, or fields that are not valid provider
/// dependencies.
/// Declares the path prefix for a controller type.
///
/// `#[controller]` is valid on structs that own HTTP handler methods. It is
/// metadata-generating behavior by itself: it records the controller prefix and
/// exposes controller metadata used by `#[routes]`, CLI route inspection, and
/// OpenAPI tooling.
///
/// Basic syntax:
///
/// ```ignore
/// #[controller("/users")]
/// struct UsersController {
/// service: UsersService,
/// }
/// ```
///
/// `#[controller("/users")]` combines with route methods inside a `#[routes]`
/// impl block. The final route path is the controller prefix plus each method's
/// route path, for example `"/users"` and `"/:id"` become `"/users/:id"`.
/// Common errors are missing the string literal path, using an empty dynamic
/// segment such as `"/:"`, or expecting this macro alone to register Tower
/// routes. Executable routing is generated by `#[routes]`.
/// Generates route metadata and executable Axum routers for a controller impl.
///
/// `#[routes]` is valid on inherent `impl` blocks for controller types. It is
/// both metadata-generating and executable behavior: the macro validates route
/// attributes, emits `routes()` metadata for CLI/OpenAPI tooling, and generates
/// `try_into_router()` plus `into_router()` when route methods are present.
///
/// Basic syntax:
///
/// ```ignore
/// #[controller("/users")]
/// struct UsersController;
///
/// #[routes]
/// impl UsersController {
/// #[get("/:id")]
/// async fn show(
/// &self,
/// nidus::prelude::Path(id): nidus::prelude::Path<String>,
/// scoped: nidus::prelude::RequestScoped<nidus::prelude::RequestContext>,
/// ) -> nidus::prelude::Json<UserDto> {
/// nidus::prelude::Json(UserDto::from_id(id, scoped.request_id().to_owned()))
/// }
/// }
/// ```
///
/// `try_into_router()` returns `Result<Router, RoutePathError>` and should be
/// preferred when path validation errors must be handled. `into_router()` unwraps
/// that result and panics with the route error, which is convenient in examples
/// and tests where invalid static paths are programming mistakes.
///
/// Handler parameters are normal Axum extractors such as `Path<T>`, `Query<T>`,
/// `Json<T>`, and Nidus extractors such as `RequestScoped<T>`. Guards, pipes,
/// validation, and OpenAPI attributes attached to methods are stored in route
/// metadata; Tower layers and extractors are still the execution path for actual
/// request enforcement and transformation. Common errors include using route
/// macros outside a `#[routes]` impl, omitting `&self`, duplicating method
/// metadata, or assuming guard/pipe metadata automatically installs middleware.
/// Declares a GET handler inside a `#[routes]` impl block.
///
/// `#[get]` is valid only on async controller methods that receive `&self`. It
/// is metadata for `#[routes]`; the executable Axum route is generated when the
/// enclosing impl block is expanded.
///
/// Basic syntax:
///
/// ```ignore
/// #[routes]
/// impl UsersController {
/// #[get("/:id")]
/// async fn show(&self, Path(id): Path<String>) -> Json<UserDto> {
/// Json(self.service.find(id).await)
/// }
/// }
/// ```
///
/// The path is relative to the controller prefix. Method parameters can use Axum
/// extractors such as `Path`, `Query`, and `Json`, plus Nidus extractors such as
/// `RequestScoped<T>`. Route metadata feeds `routes()`, CLI route output, and
/// OpenAPI generation when combined with `#[openapi]`. Common errors are
/// omitting the path string, using invalid path parameters, or placing the
/// method outside `#[routes]`.
/// Declares a POST handler inside a `#[routes]` impl block.
///
/// `#[post]` has the same placement and generation rules as `#[get]`, but emits
/// POST route metadata and executable Axum routing from the enclosing
/// `#[routes]` impl block.
///
/// Basic syntax:
///
/// ```ignore
/// #[routes]
/// impl UsersController {
/// #[post("/")]
/// async fn create(&self, Json(input): Json<CreateUser>) -> (StatusCode, Json<UserDto>) {
/// (StatusCode::CREATED, Json(self.service.create(input).await))
/// }
/// }
/// ```
///
/// Use `Json<T>`, `Query<T>`, `Path<T>`, request extensions, or
/// `RequestScoped<T>` exactly as you would in Axum handlers. Common errors are
/// treating guard or pipe metadata as request execution by itself, duplicating
/// route method attributes, or returning a type that does not implement
/// `IntoResponse`.
/// Declares a PUT handler inside a `#[routes]` impl block.
///
/// `#[put]` records PUT route metadata and participates in `#[routes]`
/// generation of `routes()`, `try_into_router()`, and `into_router()`.
///
/// Basic syntax:
///
/// ```ignore
/// #[routes]
/// impl UsersController {
/// #[put("/:id")]
/// async fn replace(&self, Path(id): Path<String>, Json(input): Json<UserInput>) -> Json<UserDto> {
/// Json(self.service.replace(id, input).await)
/// }
/// }
/// ```
///
/// The macro is valid only on methods with a receiver. It does not run request
/// validation by itself; attach extractor types, Tower layers, validation pipes,
/// or explicit application logic for executable behavior.
/// Declares a PATCH handler inside a `#[routes]` impl block.
///
/// `#[patch]` records PATCH route metadata and is consumed by `#[routes]` to
/// build the controller router.
///
/// Basic syntax:
///
/// ```ignore
/// #[routes]
/// impl UsersController {
/// #[patch("/:id")]
/// async fn update(&self, Path(id): Path<String>, Json(input): Json<UpdateUser>) -> Json<UserDto> {
/// Json(self.service.update(id, input).await)
/// }
/// }
/// ```
///
/// Use this macro for partial update endpoints where the handler return type is
/// any Axum-compatible `IntoResponse`. Common errors are invalid relative paths
/// and forgetting that the controller prefix is prepended by generated router
/// construction.
/// Declares a DELETE handler inside a `#[routes]` impl block.
///
/// `#[delete]` records DELETE route metadata and is consumed by `#[routes]` to
/// build executable router methods.
///
/// Basic syntax:
///
/// ```ignore
/// #[routes]
/// impl UsersController {
/// #[delete("/:id")]
/// async fn delete(&self, Path(id): Path<String>) -> StatusCode {
/// self.service.delete(id).await;
/// StatusCode::NO_CONTENT
/// }
/// }
/// ```
///
/// The generated route composes with normal Axum extractors and responses.
/// Guard, pipe, validate, and OpenAPI annotations on the same method are
/// available through route metadata for tooling and explicit integration code.
/// Declares OpenAPI metadata for a controller route method.
///
/// `#[openapi]` is valid only on methods inside a `#[routes]` impl block. It is
/// metadata-only behavior: it does not change request execution, but it enriches
/// the `RouteMetadata` emitted by `#[routes]` so CLI and OpenAPI builders can
/// generate useful documentation.
///
/// Basic syntax:
///
/// ```ignore
/// #[routes]
/// impl UsersController {
/// #[get("/:id")]
/// #[openapi(
/// summary = "Fetch a user by id",
/// tags = ["users"],
/// status = 200,
/// response = UserDto,
/// )]
/// async fn show(&self, Path(id): Path<String>) -> Json<UserDto> {
/// Json(self.service.find(id).await)
/// }
/// }
/// ```
///
/// Supported metadata includes summaries, tags, status codes, request schemas,
/// and response schemas. DTO schema names are recorded for tooling; they do not
/// serialize or validate requests at runtime. Common errors include missing
/// `summary`, non-string tags, invalid status values, duplicate metadata, or
/// placing the attribute outside a route method.
/// Declares guard metadata for a controller route method.
///
/// `#[guard]` is valid only on methods inside a `#[routes]` impl block. It is
/// metadata-only behavior in the macro layer: the guard type is recorded on the
/// generated `RouteMetadata`, while actual request enforcement should be wired
/// through Tower layers, Axum extractors, or explicit handler/service code.
///
/// Basic syntax:
///
/// ```ignore
/// #[routes]
/// impl AdminController {
/// #[get("/reports")]
/// #[guard(AdminGuard)]
/// async fn reports(&self) -> Json<Vec<ReportDto>> {
/// Json(self.service.reports().await)
/// }
/// }
/// ```
///
/// Guard metadata composes with `nidus-auth` guard implementations and CLI or
/// OpenAPI route inspection. Common errors are omitting the guard type, using
/// the attribute on a non-route item, or assuming metadata alone installs a
/// `GuardLayer`.
/// Declares pipe metadata for a controller route method.
///
/// `#[pipe]` is valid only on methods inside a `#[routes]` impl block. It is
/// metadata-only behavior in the macro layer: the pipe type is recorded on the
/// generated route metadata for tooling and explicit integration, but request
/// transformation still happens through extractors, validation wrappers, Tower
/// layers, or handler code.
///
/// Basic syntax:
///
/// ```ignore
/// #[routes]
/// impl UsersController {
/// #[post("/")]
/// #[pipe(TrimInputPipe)]
/// async fn create(&self, Json(input): Json<CreateUser>) -> Json<UserDto> {
/// Json(self.service.create(input).await)
/// }
/// }
/// ```
///
/// Pipes compose with validation metadata and Nidus validation types, but the
/// macro intentionally avoids hidden runtime mutation. Common errors include
/// omitting the pipe type or placing `#[pipe]` outside a controller route method.
/// Marks a controller route method as participating in validation metadata.
///
/// `#[validate]` is valid only on methods inside a `#[routes]` impl block. It is
/// metadata-only behavior: generated `RouteMetadata` records that the route is
/// intended to use validation, while runtime validation should be expressed with
/// typed extractors such as `ValidatedJson<T>`, validation pipes, Tower layers,
/// or explicit handler logic.
///
/// Basic syntax:
///
/// ```ignore
/// #[routes]
/// impl UsersController {
/// #[post("/")]
/// #[validate]
/// async fn create(&self, input: ValidatedJson<CreateUser>) -> Json<UserDto> {
/// Json(self.service.create(input.into_inner()).await)
/// }
/// }
/// ```
///
/// The attribute composes with `#[openapi]`, `#[guard]`, and `#[pipe]` by adding
/// validation intent to the same route metadata record. Common errors are using
/// it outside a route method or expecting validation to run without a validation
/// extractor, pipe, or layer in the executable request path.