Skip to content

Commit df2b421

Browse files
[Rust Server] Sort operations so that the ones with fewest params come first (#19368)
* [Rust Server] Sort operations so that the ones with fewest params come first This resolves things correctly per https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#pathsObject - "When matching URLs, concrete (non-templated) paths would be matched before their templated counterparts." * Update samples * [Rust Server] Fix tabs vs spaces --------- Co-authored-by: Rob Day <Robert.Day@metaswitch.com>
1 parent fd62e38 commit df2b421

18 files changed

Lines changed: 1658 additions & 1648 deletions

File tree

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import joptsimple.internal.Strings;
3232
import lombok.Setter;
3333
import org.apache.commons.io.FilenameUtils;
34+
import org.apache.commons.lang3.ObjectUtils;
3435
import org.apache.commons.lang3.StringUtils;
3536
import org.openapitools.codegen.*;
3637
import org.openapitools.codegen.meta.features.*;
@@ -803,6 +804,15 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
803804
postProcessOperationWithModels(op, allModels);
804805
}
805806

807+
operationList.sort((one, another) -> {
808+
int params_compare = ObjectUtils.compare(one.pathParams.size(), another.pathParams.size());
809+
if (params_compare == 0) {
810+
return ObjectUtils.compare(one.operationId, another.operationId);
811+
} else {
812+
return params_compare;
813+
}
814+
});
815+
806816
return objs;
807817
}
808818

samples/server/petstore/rust-server/output/openapi-v3/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ Method | HTTP request | Description
122122
[****](docs/default_api.md#) | **GET** /any-of |
123123
[****](docs/default_api.md#) | **POST** /callback-with-header |
124124
[****](docs/default_api.md#) | **GET** /complex-query-param |
125-
[****](docs/default_api.md#) | **GET** /enum_in_path/{path_param} |
126125
[****](docs/default_api.md#) | **GET** /json-complex-query-param |
127126
[****](docs/default_api.md#) | **GET** /mandatory-request-header |
128127
[****](docs/default_api.md#) | **GET** /merge-patch-json |
@@ -143,6 +142,7 @@ Method | HTTP request | Description
143142
[****](docs/default_api.md#) | **PUT** /xml_other |
144143
[****](docs/default_api.md#) | **POST** /xml | Post an array
145144
[****](docs/default_api.md#) | **PUT** /xml |
145+
[****](docs/default_api.md#) | **GET** /enum_in_path/{path_param} |
146146
[**CreateRepo**](docs/repo_api.md#CreateRepo) | **POST** /repos |
147147
[**GetRepoInfo**](docs/repo_api.md#GetRepoInfo) | **GET** /repos/{repoId} |
148148

samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ Method | HTTP request | Description
77
****](default_api.md#) | **GET** /any-of |
88
****](default_api.md#) | **POST** /callback-with-header |
99
****](default_api.md#) | **GET** /complex-query-param |
10-
****](default_api.md#) | **GET** /enum_in_path/{path_param} |
1110
****](default_api.md#) | **GET** /json-complex-query-param |
1211
****](default_api.md#) | **GET** /mandatory-request-header |
1312
****](default_api.md#) | **GET** /merge-patch-json |
@@ -28,6 +27,7 @@ Method | HTTP request | Description
2827
****](default_api.md#) | **PUT** /xml_other |
2928
****](default_api.md#) | **POST** /xml | Post an array
3029
****](default_api.md#) | **PUT** /xml |
30+
****](default_api.md#) | **GET** /enum_in_path/{path_param} |
3131

3232

3333
# ****
@@ -119,31 +119,6 @@ No authorization required
119119

120120
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
121121

122-
# ****
123-
> (path_param)
124-
125-
126-
### Required Parameters
127-
128-
Name | Type | Description | Notes
129-
------------- | ------------- | ------------- | -------------
130-
**path_param** | [****](.md)| |
131-
132-
### Return type
133-
134-
(empty response body)
135-
136-
### Authorization
137-
138-
No authorization required
139-
140-
### HTTP request headers
141-
142-
- **Content-Type**: Not defined
143-
- **Accept**: Not defined
144-
145-
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
146-
147122
# ****
148123
> (optional)
149124
@@ -677,3 +652,28 @@ No authorization required
677652

678653
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
679654

655+
# ****
656+
> (path_param)
657+
658+
659+
### Required Parameters
660+
661+
Name | Type | Description | Notes
662+
------------- | ------------- | ------------- | -------------
663+
**path_param** | [****](.md)| |
664+
665+
### Return type
666+
667+
(empty response body)
668+
669+
### Authorization
670+
671+
No authorization required
672+
673+
### HTTP request headers
674+
675+
- **Content-Type**: Not defined
676+
- **Accept**: Not defined
677+
678+
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
679+

samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use openapi_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models,
99
AnyOfGetResponse,
1010
CallbackWithHeaderPostResponse,
1111
ComplexQueryParamGetResponse,
12-
EnumInPathPathParamGetResponse,
1312
JsonComplexQueryParamGetResponse,
1413
MandatoryRequestHeaderGetResponse,
1514
MergePatchJsonGetResponse,
@@ -30,6 +29,7 @@ use openapi_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models,
3029
XmlOtherPutResponse,
3130
XmlPostResponse,
3231
XmlPutResponse,
32+
EnumInPathPathParamGetResponse,
3333
CreateRepoResponse,
3434
GetRepoInfoResponse,
3535
};
@@ -177,14 +177,6 @@ fn main() {
177177
));
178178
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
179179
},
180-
/* Disabled because there's no example.
181-
Some("EnumInPathPathParamGet") => {
182-
let result = rt.block_on(client.enum_in_path_path_param_get(
183-
???
184-
));
185-
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
186-
},
187-
*/
188180
Some("JsonComplexQueryParamGet") => {
189181
let result = rt.block_on(client.json_complex_query_param_get(
190182
Some(&Vec::new())
@@ -298,6 +290,14 @@ fn main() {
298290
));
299291
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
300292
},
293+
/* Disabled because there's no example.
294+
Some("EnumInPathPathParamGet") => {
295+
let result = rt.block_on(client.enum_in_path_path_param_get(
296+
???
297+
));
298+
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
299+
},
300+
*/
301301
Some("CreateRepo") => {
302302
let result = rt.block_on(client.create_repo(
303303
serde_json::from_str::<models::ObjectParam>(r#"{"requiredParam":true}"#).expect("Failed to parse JSON example")

samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ use openapi_v3::{
105105
AnyOfGetResponse,
106106
CallbackWithHeaderPostResponse,
107107
ComplexQueryParamGetResponse,
108-
EnumInPathPathParamGetResponse,
109108
JsonComplexQueryParamGetResponse,
110109
MandatoryRequestHeaderGetResponse,
111110
MergePatchJsonGetResponse,
@@ -126,6 +125,7 @@ use openapi_v3::{
126125
XmlOtherPutResponse,
127126
XmlPostResponse,
128127
XmlPutResponse,
128+
EnumInPathPathParamGetResponse,
129129
CreateRepoResponse,
130130
GetRepoInfoResponse,
131131
};
@@ -163,15 +163,6 @@ impl<C> Api<C> for Server<C> where C: Has<XSpanIdString> + Send + Sync
163163
Err(ApiError("Api-Error: Operation is NOT implemented".into()))
164164
}
165165

166-
async fn enum_in_path_path_param_get(
167-
&self,
168-
path_param: models::StringEnum,
169-
context: &C) -> Result<EnumInPathPathParamGetResponse, ApiError>
170-
{
171-
info!("enum_in_path_path_param_get({:?}) - X-Span-ID: {:?}", path_param, context.get().0.clone());
172-
Err(ApiError("Api-Error: Operation is NOT implemented".into()))
173-
}
174-
175166
async fn json_complex_query_param_get(
176167
&self,
177168
list_of_strings: Option<&Vec<models::StringObject>>,
@@ -348,6 +339,15 @@ impl<C> Api<C> for Server<C> where C: Has<XSpanIdString> + Send + Sync
348339
Err(ApiError("Api-Error: Operation is NOT implemented".into()))
349340
}
350341

342+
async fn enum_in_path_path_param_get(
343+
&self,
344+
path_param: models::StringEnum,
345+
context: &C) -> Result<EnumInPathPathParamGetResponse, ApiError>
346+
{
347+
info!("enum_in_path_path_param_get({:?}) - X-Span-ID: {:?}", path_param, context.get().0.clone());
348+
Err(ApiError("Api-Error: Operation is NOT implemented".into()))
349+
}
350+
351351
async fn create_repo(
352352
&self,
353353
object_param: models::ObjectParam,

samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ use crate::{Api,
3939
AnyOfGetResponse,
4040
CallbackWithHeaderPostResponse,
4141
ComplexQueryParamGetResponse,
42-
EnumInPathPathParamGetResponse,
4342
JsonComplexQueryParamGetResponse,
4443
MandatoryRequestHeaderGetResponse,
4544
MergePatchJsonGetResponse,
@@ -60,6 +59,7 @@ use crate::{Api,
6059
XmlOtherPutResponse,
6160
XmlPostResponse,
6261
XmlPutResponse,
62+
EnumInPathPathParamGetResponse,
6363
CreateRepoResponse,
6464
GetRepoInfoResponse
6565
};
@@ -667,76 +667,6 @@ impl<S, C> Api<C> for Client<S, C> where
667667
}
668668
}
669669

670-
async fn enum_in_path_path_param_get(
671-
&self,
672-
param_path_param: models::StringEnum,
673-
context: &C) -> Result<EnumInPathPathParamGetResponse, ApiError>
674-
{
675-
let mut client_service = self.client_service.clone();
676-
let mut uri = format!(
677-
"{}/enum_in_path/{path_param}",
678-
self.base_path
679-
,path_param=utf8_percent_encode(&param_path_param.to_string(), ID_ENCODE_SET)
680-
);
681-
682-
// Query parameters
683-
let query_string = {
684-
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
685-
query_string.finish()
686-
};
687-
if !query_string.is_empty() {
688-
uri += "?";
689-
uri += &query_string;
690-
}
691-
692-
let uri = match Uri::from_str(&uri) {
693-
Ok(uri) => uri,
694-
Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))),
695-
};
696-
697-
let mut request = match Request::builder()
698-
.method("GET")
699-
.uri(uri)
700-
.body(Body::empty()) {
701-
Ok(req) => req,
702-
Err(e) => return Err(ApiError(format!("Unable to create request: {}", e)))
703-
};
704-
705-
let header = HeaderValue::from_str(Has::<XSpanIdString>::get(context).0.as_str());
706-
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
707-
Ok(h) => h,
708-
Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))
709-
});
710-
711-
let response = client_service.call((request, context.clone()))
712-
.map_err(|e| ApiError(format!("No response received: {}", e))).await?;
713-
714-
match response.status().as_u16() {
715-
200 => {
716-
Ok(
717-
EnumInPathPathParamGetResponse::Success
718-
)
719-
}
720-
code => {
721-
let headers = response.headers().clone();
722-
let body = response.into_body()
723-
.take(100)
724-
.into_raw().await;
725-
Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
726-
code,
727-
headers,
728-
match body {
729-
Ok(body) => match String::from_utf8(body) {
730-
Ok(body) => body,
731-
Err(e) => format!("<Body was not UTF8: {:?}>", e),
732-
},
733-
Err(e) => format!("<Failed to read body: {}>", e),
734-
}
735-
)))
736-
}
737-
}
738-
}
739-
740670
async fn json_complex_query_param_get(
741671
&self,
742672
param_list_of_strings: Option<&Vec<models::StringObject>>,
@@ -2597,6 +2527,76 @@ impl<S, C> Api<C> for Client<S, C> where
25972527
}
25982528
}
25992529

2530+
async fn enum_in_path_path_param_get(
2531+
&self,
2532+
param_path_param: models::StringEnum,
2533+
context: &C) -> Result<EnumInPathPathParamGetResponse, ApiError>
2534+
{
2535+
let mut client_service = self.client_service.clone();
2536+
let mut uri = format!(
2537+
"{}/enum_in_path/{path_param}",
2538+
self.base_path
2539+
,path_param=utf8_percent_encode(&param_path_param.to_string(), ID_ENCODE_SET)
2540+
);
2541+
2542+
// Query parameters
2543+
let query_string = {
2544+
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
2545+
query_string.finish()
2546+
};
2547+
if !query_string.is_empty() {
2548+
uri += "?";
2549+
uri += &query_string;
2550+
}
2551+
2552+
let uri = match Uri::from_str(&uri) {
2553+
Ok(uri) => uri,
2554+
Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))),
2555+
};
2556+
2557+
let mut request = match Request::builder()
2558+
.method("GET")
2559+
.uri(uri)
2560+
.body(Body::empty()) {
2561+
Ok(req) => req,
2562+
Err(e) => return Err(ApiError(format!("Unable to create request: {}", e)))
2563+
};
2564+
2565+
let header = HeaderValue::from_str(Has::<XSpanIdString>::get(context).0.as_str());
2566+
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
2567+
Ok(h) => h,
2568+
Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))
2569+
});
2570+
2571+
let response = client_service.call((request, context.clone()))
2572+
.map_err(|e| ApiError(format!("No response received: {}", e))).await?;
2573+
2574+
match response.status().as_u16() {
2575+
200 => {
2576+
Ok(
2577+
EnumInPathPathParamGetResponse::Success
2578+
)
2579+
}
2580+
code => {
2581+
let headers = response.headers().clone();
2582+
let body = response.into_body()
2583+
.take(100)
2584+
.into_raw().await;
2585+
Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
2586+
code,
2587+
headers,
2588+
match body {
2589+
Ok(body) => match String::from_utf8(body) {
2590+
Ok(body) => body,
2591+
Err(e) => format!("<Body was not UTF8: {:?}>", e),
2592+
},
2593+
Err(e) => format!("<Failed to read body: {}>", e),
2594+
}
2595+
)))
2596+
}
2597+
}
2598+
}
2599+
26002600
async fn create_repo(
26012601
&self,
26022602
param_object_param: models::ObjectParam,

0 commit comments

Comments
 (0)