a3s_boot/routing/route/
openapi.rs1use super::definition::RouteDefinition;
2#[cfg(feature = "openapi-schemas")]
3use crate::{openapi_schema_name, BootError, Result};
4use crate::{
5 OpenApiParameter, OpenApiRequestBody, OpenApiResponse, OpenApiRouteMetadata, OpenApiSchema,
6 OpenApiSecurityRequirement,
7};
8
9impl RouteDefinition {
10 pub fn with_openapi(mut self, metadata: OpenApiRouteMetadata) -> Self {
11 self.openapi = metadata;
12 self
13 }
14
15 pub fn with_tag(mut self, tag: impl Into<String>) -> Self {
16 let tag = tag.into();
17 if !self.openapi.tags.contains(&tag) {
18 self.openapi.tags.push(tag);
19 }
20 self
21 }
22
23 pub fn with_operation_id(mut self, operation_id: impl Into<String>) -> Self {
24 self.openapi.operation_id = Some(operation_id.into());
25 self
26 }
27
28 pub fn with_summary(mut self, summary: impl Into<String>) -> Self {
29 self.openapi.summary = Some(summary.into());
30 self
31 }
32
33 pub fn with_description(mut self, description: impl Into<String>) -> Self {
34 self.openapi.description = Some(description.into());
35 self
36 }
37
38 pub fn with_deprecated(mut self) -> Self {
39 self.openapi.deprecated = true;
40 self
41 }
42
43 pub fn hide_from_openapi(mut self) -> Self {
44 self.openapi.hidden = true;
45 self
46 }
47
48 pub fn with_parameter(mut self, parameter: OpenApiParameter) -> Self {
49 upsert_parameter(&mut self.openapi.parameters, parameter);
50 self
51 }
52
53 pub fn with_path_parameter(self, name: impl Into<String>, schema: OpenApiSchema) -> Self {
54 self.with_parameter(OpenApiParameter::path(name, schema))
55 }
56
57 pub fn with_query_parameter(
58 self,
59 name: impl Into<String>,
60 required: bool,
61 schema: OpenApiSchema,
62 ) -> Self {
63 self.with_parameter(OpenApiParameter::query(name, required, schema))
64 }
65
66 pub fn with_header_parameter(
67 self,
68 name: impl Into<String>,
69 required: bool,
70 schema: OpenApiSchema,
71 ) -> Self {
72 self.with_parameter(OpenApiParameter::header(name, required, schema))
73 }
74
75 pub fn with_request_body(mut self, request_body: OpenApiRequestBody) -> Self {
76 self.openapi.request_body = Some(request_body);
77 self
78 }
79
80 pub fn with_json_request_body(self, schema: OpenApiSchema) -> Self {
81 self.with_request_body(OpenApiRequestBody::json(schema))
82 }
83
84 pub fn with_response(mut self, status: u16, response: OpenApiResponse) -> Self {
85 self.openapi.responses.insert(status.to_string(), response);
86 self
87 }
88
89 pub fn with_default_response(mut self, response: OpenApiResponse) -> Self {
90 self.openapi
91 .responses
92 .insert("default".to_string(), response);
93 self
94 }
95
96 pub fn with_json_response(
97 self,
98 status: u16,
99 description: impl Into<String>,
100 schema: OpenApiSchema,
101 ) -> Self {
102 self.with_response(status, OpenApiResponse::json(description, schema))
103 }
104
105 pub fn with_security_requirement(mut self, requirement: OpenApiSecurityRequirement) -> Self {
106 self.openapi.security.push(requirement);
107 self
108 }
109
110 pub fn with_bearer_auth(self) -> Self {
111 let mut requirement = OpenApiSecurityRequirement::new();
112 requirement.insert("bearerAuth".to_string(), Vec::new());
113 self.with_security_requirement(requirement)
114 }
115
116 pub fn with_schema_component(mut self, name: impl Into<String>, schema: OpenApiSchema) -> Self {
117 self.openapi.schema_components.insert(name.into(), schema);
118 self
119 }
120
121 #[cfg(feature = "openapi-schemas")]
122 pub fn try_with_json_schema_component<T>(self) -> Result<Self>
123 where
124 T: schemars::JsonSchema,
125 {
126 let schema = OpenApiSchema::json_schema::<T>()
127 .map_err(|error| BootError::Internal(error.to_string()))?;
128 Ok(self.with_schema_component(openapi_schema_name::<T>(), schema))
129 }
130}
131
132fn upsert_parameter(parameters: &mut Vec<OpenApiParameter>, parameter: OpenApiParameter) {
133 if let Some(existing) = parameters
134 .iter_mut()
135 .find(|existing| existing.location == parameter.location && existing.name == parameter.name)
136 {
137 *existing = parameter;
138 return;
139 }
140
141 parameters.push(parameter);
142}