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
//! Axum backend proc-macro for `openapi-trait`.
//!
//! This crate is not intended for direct use. Use the
//! [`openapi-trait`](https://docs.rs/openapi-trait) crate instead, which
//! re-exports the [`openapi_trait`] attribute macro from here as
//! `openapi_trait::axum`.
/// Code-generation modules for the axum backend.
use TokenStream;
use Span;
use quote;
use ;
/// Generates typed Rust code from an `OpenAPI` specification file.
///
/// Apply this attribute to a `mod` block. The macro reads the `OpenAPI`
/// document at the given path (resolved relative to `CARGO_MANIFEST_DIR`) at
/// compile time and replaces the module's contents with:
///
/// - Schema structs derived from `components/schemas`
/// - A `{OperationId}Request` struct per operation (bundles path, query,
/// header params and the request body)
/// - Per-operation `{OperationId}Response` enums implementing
/// [`axum::response::IntoResponse`](https://docs.rs/axum/latest/axum/response/trait.IntoResponse.html)
/// - A `{Title}Api` trait with one `async fn` per operation (keyed by
/// `operationId`). Trait methods have a default implementation that returns
/// `500 Internal Server Error`, so you only need to override the operations
/// your server handles.
/// - A `router` method on the trait that wires all operations to an
/// [`axum::Router`](https://docs.rs/axum/latest/axum/struct.Router.html)
///
/// The crate recompiles automatically whenever the spec file changes.
///
/// # Arguments
///
/// First positional argument: path to the `OpenAPI` YAML or JSON file,
/// relative to the crate root (`CARGO_MANIFEST_DIR`).
///
/// # Examples
///
/// ```rust,ignore
/// #[openapi_trait::axum("openapi/petstore.yaml")]
/// pub mod petstore {}
///
/// #[derive(Clone)]
/// struct MyServer;
///
/// impl petstore::PetstoreApi for MyServer {
/// type Error = std::convert::Infallible;
///
/// async fn get_pet_by_id(
/// &self,
/// req: petstore::GetPetByIdRequest,
/// _state: axum::extract::State<()>,
/// _headers: axum::http::HeaderMap,
/// ) -> Result<petstore::GetPetByIdResponse, Self::Error> {
/// Ok(petstore::GetPetByIdResponse::Status200(petstore::Pet {
/// id: Some(req.pet_id),
/// name: "doggie".into(),
/// photo_urls: vec![],
/// category: None,
/// tags: None,
/// status: None,
/// }))
/// }
/// }
///
/// let app = MyServer.router().with_state(());
/// ```
///
/// # Errors
///
/// The macro emits a compile error if:
///
/// - The file cannot be found or read.
/// - The `OpenAPI` document is malformed or cannot be parsed.
/// - An operation is missing an `operationId`.
/// Run the core macro logic with the resolved spec path literal.