Skip to main content

fastapi_macros/
lib.rs

1//! Procedural macros for fastapi_rust.
2//!
3//! This crate provides the following macros:
4//!
5//! - Route macros: `#[get]`, `#[post]`, `#[put]`, `#[delete]`, `#[patch]`, `#[head]`, `#[options]`
6//! - `#[derive(Validate)]` for compile-time validation
7//! - `#[derive(JsonSchema)]` for OpenAPI schema generation
8//!
9//! # Role In The System
10//!
11//! `fastapi-macros` is the compile-time glue that keeps the runtime minimal.
12//! It analyzes handler signatures, generates route registration metadata, and
13//! enforces validation/schema rules without any runtime reflection. The emitted
14//! code targets types from `fastapi-core` and `fastapi-openapi`, and is re-exported
15//! by the `fastapi` facade crate for user ergonomics.
16//!
17//! # Example
18//!
19//! ```ignore
20//! use fastapi::prelude::*;
21//!
22//! #[get("/items/{id}")]
23//! async fn get_item(cx: &Cx, id: Path<i64>) -> Json<Item> {
24//!     // ...
25//! }
26//! ```
27
28use proc_macro::TokenStream;
29
30mod openapi;
31mod param;
32mod route;
33mod validate;
34
35/// Mark a function as a GET handler.
36///
37/// # Example
38///
39/// ```ignore
40/// #[get("/items")]
41/// async fn list_items() -> Json<Vec<Item>> {
42///     // ...
43/// }
44/// ```
45#[proc_macro_attribute]
46pub fn get(attr: TokenStream, item: TokenStream) -> TokenStream {
47    route::route_impl("Get", attr, item)
48}
49
50/// Mark a function as a POST handler.
51#[proc_macro_attribute]
52pub fn post(attr: TokenStream, item: TokenStream) -> TokenStream {
53    route::route_impl("Post", attr, item)
54}
55
56/// Mark a function as a PUT handler.
57#[proc_macro_attribute]
58pub fn put(attr: TokenStream, item: TokenStream) -> TokenStream {
59    route::route_impl("Put", attr, item)
60}
61
62/// Mark a function as a DELETE handler.
63#[proc_macro_attribute]
64pub fn delete(attr: TokenStream, item: TokenStream) -> TokenStream {
65    route::route_impl("Delete", attr, item)
66}
67
68/// Mark a function as a PATCH handler.
69#[proc_macro_attribute]
70pub fn patch(attr: TokenStream, item: TokenStream) -> TokenStream {
71    route::route_impl("Patch", attr, item)
72}
73
74/// Mark a function as a HEAD handler.
75///
76/// HEAD requests are identical to GET but return only headers, not body.
77/// Useful for checking resource existence or metadata without full content.
78///
79/// # Example
80///
81/// ```ignore
82/// #[head("/items/{id}")]
83/// async fn head_item(id: Path<i64>) -> StatusCode {
84///     StatusCode::OK
85/// }
86/// ```
87#[proc_macro_attribute]
88pub fn head(attr: TokenStream, item: TokenStream) -> TokenStream {
89    route::route_impl("Head", attr, item)
90}
91
92/// Mark a function as an OPTIONS handler.
93///
94/// OPTIONS requests return allowed methods and CORS headers for a resource.
95///
96/// # Example
97///
98/// ```ignore
99/// #[options("/items")]
100/// async fn options_items() -> Response {
101///     Response::builder()
102///         .header("Allow", "GET, POST, OPTIONS")
103///         .body(())
104/// }
105/// ```
106#[proc_macro_attribute]
107pub fn options(attr: TokenStream, item: TokenStream) -> TokenStream {
108    route::route_impl("Options", attr, item)
109}
110
111/// Derive validation for a struct.
112///
113/// # Validation Attributes
114///
115/// - `#[validate(length(min = 1, max = 100))]` - String length
116/// - `#[validate(range(min = 0.0, max = 1.0))]` - Numeric range
117/// - `#[validate(email)]` - Email format
118/// - `#[validate(regex = "pattern")]` - Regex pattern
119///
120/// # Example
121///
122/// ```ignore
123/// #[derive(Validate)]
124/// struct CreateUser {
125///     #[validate(length(min = 1, max = 50))]
126///     name: String,
127///     #[validate(email)]
128///     email: String,
129/// }
130/// ```
131#[proc_macro_derive(Validate, attributes(validate))]
132pub fn derive_validate(input: TokenStream) -> TokenStream {
133    validate::derive_validate_impl(input)
134}
135
136/// Derive JSON Schema for OpenAPI.
137///
138/// # Example
139///
140/// ```ignore
141/// #[derive(JsonSchema)]
142/// struct Item {
143///     id: i64,
144///     name: String,
145///     #[schema(nullable)]
146///     description: Option<String>,
147/// }
148/// ```
149#[proc_macro_derive(JsonSchema, attributes(schema))]
150pub fn derive_json_schema(input: TokenStream) -> TokenStream {
151    openapi::derive_json_schema_impl(input)
152}