1use crate::error::RoutePathError;
2use serde_json::Value;
3
4use super::join_paths;
5
6pub type OpenApiSchemaRegistrar =
8 fn(&mut Vec<(String, Value)>) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
9
10#[derive(Clone, Debug)]
12pub struct RouteMetadata {
13 method: &'static str,
14 path: &'static str,
15 summary: Option<&'static str>,
16 tags: &'static [&'static str],
17 response_status: Option<http::StatusCode>,
18 request_schema: Option<&'static str>,
19 response_schema: Option<&'static str>,
20 request_schema_registrar: Option<OpenApiSchemaRegistrar>,
21 response_schema_registrar: Option<OpenApiSchemaRegistrar>,
22 guards: &'static [&'static str],
23 pipes: &'static [&'static str],
24 validates: bool,
25}
26
27impl RouteMetadata {
28 pub const fn new(method: &'static str, path: &'static str) -> Self {
30 Self {
31 method,
32 path,
33 summary: None,
34 tags: &[],
35 response_status: None,
36 request_schema: None,
37 response_schema: None,
38 request_schema_registrar: None,
39 response_schema_registrar: None,
40 guards: &[],
41 pipes: &[],
42 validates: false,
43 }
44 }
45
46 pub const fn with_summary(
48 method: &'static str,
49 path: &'static str,
50 summary: &'static str,
51 ) -> Self {
52 Self {
53 method,
54 path,
55 summary: Some(summary),
56 tags: &[],
57 response_status: None,
58 request_schema: None,
59 response_schema: None,
60 request_schema_registrar: None,
61 response_schema_registrar: None,
62 guards: &[],
63 pipes: &[],
64 validates: false,
65 }
66 }
67
68 pub const fn with_annotations(
70 method: &'static str,
71 path: &'static str,
72 summary: Option<&'static str>,
73 guards: &'static [&'static str],
74 pipes: &'static [&'static str],
75 validates: bool,
76 ) -> Self {
77 Self {
78 method,
79 path,
80 summary,
81 tags: &[],
82 response_status: None,
83 request_schema: None,
84 response_schema: None,
85 request_schema_registrar: None,
86 response_schema_registrar: None,
87 guards,
88 pipes,
89 validates,
90 }
91 }
92
93 pub const fn with_openapi_annotations(
95 method: &'static str,
96 path: &'static str,
97 summary: Option<&'static str>,
98 tags: &'static [&'static str],
99 guards: &'static [&'static str],
100 pipes: &'static [&'static str],
101 validates: bool,
102 ) -> Self {
103 Self {
104 method,
105 path,
106 summary,
107 tags,
108 response_status: None,
109 request_schema: None,
110 response_schema: None,
111 request_schema_registrar: None,
112 response_schema_registrar: None,
113 guards,
114 pipes,
115 validates,
116 }
117 }
118
119 pub const fn with_openapi_schemas(
121 mut self,
122 request_schema: Option<&'static str>,
123 response_schema: Option<&'static str>,
124 ) -> Self {
125 self.request_schema = request_schema;
126 self.response_schema = response_schema;
127 self
128 }
129
130 pub fn with_openapi_schema_registrars(
132 mut self,
133 request_schema: Option<OpenApiSchemaRegistrar>,
134 response_schema: Option<OpenApiSchemaRegistrar>,
135 ) -> Self {
136 self.request_schema_registrar = request_schema;
137 self.response_schema_registrar = response_schema;
138 self
139 }
140
141 pub const fn with_openapi_status(mut self, response_status: Option<http::StatusCode>) -> Self {
143 self.response_status = response_status;
144 self
145 }
146
147 pub const fn method(&self) -> &'static str {
149 self.method
150 }
151
152 pub const fn path(&self) -> &'static str {
154 self.path
155 }
156
157 pub const fn summary(&self) -> Option<&'static str> {
159 self.summary
160 }
161
162 pub const fn tags(&self) -> &'static [&'static str] {
164 self.tags
165 }
166
167 pub const fn response_status(&self) -> Option<http::StatusCode> {
169 self.response_status
170 }
171
172 pub const fn request_schema(&self) -> Option<&'static str> {
174 self.request_schema
175 }
176
177 pub const fn response_schema(&self) -> Option<&'static str> {
179 self.response_schema
180 }
181
182 pub const fn request_schema_registrar(&self) -> Option<OpenApiSchemaRegistrar> {
184 self.request_schema_registrar
185 }
186
187 pub const fn response_schema_registrar(&self) -> Option<OpenApiSchemaRegistrar> {
189 self.response_schema_registrar
190 }
191
192 pub const fn guards(&self) -> &'static [&'static str] {
194 self.guards
195 }
196
197 pub const fn pipes(&self) -> &'static [&'static str] {
199 self.pipes
200 }
201
202 pub const fn validates(&self) -> bool {
204 self.validates
205 }
206
207 pub fn full_path(&self, controller_prefix: &str) -> String {
209 self.try_full_path(controller_prefix)
210 .unwrap_or_else(|error| panic!("{error}"))
211 }
212
213 pub fn try_full_path(&self, controller_prefix: &str) -> Result<String, RoutePathError> {
215 join_paths(controller_prefix, self.path)
216 }
217}