add exts alias to simply the templates (rust-server) (#22309)

This commit is contained in:
William Cheng 2025-11-09 15:42:14 +08:00 committed by GitHub
parent c596bb7d8a
commit 81285b75e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 185 additions and 132 deletions

View File

@ -265,6 +265,15 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
private Map<String, CodegenProperty> requiredVarsMap;
private String ref;
/**
* An alias for vendor extensions, e.g. one can use {{exts.x-something}} for cleaner template
*
* @return vendor extensions
*/
public Map<String, Object> getExts() {
return vendorExtensions;
}
@Override
public CodegenProperty getContains() {
return contains;
@ -365,7 +374,6 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
return discriminator == null ? null : discriminator.getPropertyName();
}
@Override
public String getPattern() {
return pattern;

View File

@ -79,6 +79,15 @@ public class CodegenOperation {
return params != null && !params.isEmpty();
}
/**
* An alias for vendor extensions, e.g. one can use {{exts.x-something}} for cleaner template
*
* @return vendor extensions
*/
public Map<String, Object> getExts() {
return vendorExtensions;
}
/**
* Check if there's at least one parameter
*

View File

@ -534,6 +534,15 @@ public class CodegenParameter implements IJsonSchemaValidationProperties {
return sb.toString();
}
/**
* An alias for vendor extensions, e.g. one can use {{exts.x-something}} for cleaner template
*
* @return vendor extensions
*/
public Map<String, Object> getExts() {
return vendorExtensions;
}
// use schema.getContains or content.mediaType.schema.getContains instead of this
@Override
public CodegenProperty getContains() {

View File

@ -436,6 +436,15 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
return !getRequired() || isNullable;
}
/**
* An alias for vendor extensions, e.g. one can use {{exts.x-something}} for cleaner template
*
* @return vendor extensions
*/
public Map<String, Object> getExts() {
return vendorExtensions;
}
@Override
public CodegenProperty getItems() {
return items;

View File

@ -206,6 +206,15 @@ public class CodegenResponse implements IJsonSchemaValidationProperties {
}
/**
* An alias for vendor extensions, e.g. one can use {{exts.x-something}} for cleaner template
*
* @return vendor extensions
*/
public Map<String, Object> getExts() {
return vendorExtensions;
}
// use content.mediaType.schema.getContains instead of this
@Override
public CodegenProperty getContains() {

View File

@ -38,4 +38,13 @@ public class CodegenServer {
sb.append('}');
return sb.toString();
}
/**
* An alias for vendor extensions, e.g. one can use {{exts.x-something}} for cleaner template
*
* @return vendor extensions
*/
public Map<String, Object> getExts() {
return vendorExtensions;
}
}

View File

@ -95,11 +95,11 @@ To run a client, follow one of the following simple steps:
{{#apis}}
{{#operations}}
{{#operation}}
{{#vendorExtensions}}
{{#exts}}
{{^x-no-client-example}}
cargo run --example client {{{operationId}}}
{{/x-no-client-example}}
{{/vendorExtensions}}
{{/exts}}
{{/operation}}
{{/operations}}
{{/apis}}

View File

@ -113,12 +113,12 @@ enum Operation {
{{/isBinary}}
{{#isBoolean}}
{{#isPrimitiveType}}
{{#vendorExtensions.x-provide-cli-short-opt}}
{{#exts.x-provide-cli-short-opt}}
#[clap(short, long)]
{{/vendorExtensions.x-provide-cli-short-opt}}
{{^vendorExtensions.x-provide-cli-short-opt}}
{{/exts.x-provide-cli-short-opt}}
{{^exts.x-provide-cli-short-opt}}
#[clap(long)]
{{/vendorExtensions.x-provide-cli-short-opt}}
{{/exts.x-provide-cli-short-opt}}
{{/isPrimitiveType}}
{{/isBoolean}}
{{{paramName}}}: {{^required}}Option<{{/required}}{{{dataType}}}{{^required}}>{{/required}},
@ -216,9 +216,9 @@ async fn main() -> Result<()> {
{{paramName}},
{{/allParams}}
} => {
{{#vendorExtensions.x-is-delete}}
{{#exts.x-is-delete}}
prompt(args.force, "This will delete the given entry, are you sure?")?;
{{/vendorExtensions.x-is-delete}}
{{/exts.x-is-delete}}
info!("Performing a {{operationId}} request{{^pathParams}}");{{/pathParams}}{{#pathParams}}{{#-first}} on {:?}", ({{/-first}}{{/pathParams}}
{{#pathParams}}
&{{paramName}}{{^-last}},{{/-last}}
@ -227,7 +227,7 @@ async fn main() -> Result<()> {
{{/-last}}
{{/pathParams}}
let result = client.{{{vendorExtensions.x-operation-id}}}(
let result = client.{{{exts.x-operation-id}}}(
{{#allParams}}
{{{paramName}}}{{#isArray}}.as_ref(){{/isArray}},
{{/allParams}}
@ -236,7 +236,7 @@ async fn main() -> Result<()> {
match result {
{{#responses}}
{{{operationId}}}Response::{{{vendorExtensions.x-response-id}}}
{{{operationId}}}Response::{{{exts.x-response-id}}}
{{#dataType}}
{{^hasHeaders}}
(body)
@ -257,7 +257,7 @@ async fn main() -> Result<()> {
}
{{/-last}}
{{/headers}}
=> "{{{vendorExtensions.x-response-id}}}\n".to_string()
=> "{{{exts.x-response-id}}}\n".to_string()
{{#dataType}}
+
{{/dataType}}

View File

@ -63,7 +63,7 @@ impl<T> RequestParser<T> for ApiRequestParser {
{{#urls}}
{{#requests}}
// {{{operationId}}} - {{{httpMethod}}} {{{path}}}
hyper::Method::{{{vendorExtensions.x-http-method}}} if path.matched(paths::ID_{{{vendorExtensions.x-path-id}}}) => Some("{{{operationId}}}"),
hyper::Method::{{{exts.x-http-method}}} if path.matched(paths::ID_{{{exts.x-path-id}}}) => Some("{{{operationId}}}"),
{{/requests}}
{{/urls}}
{{/callbacks}}

View File

@ -1,11 +1,11 @@
#[allow(clippy::vec_init_then_push)]
async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}(
async fn {{#exts}}{{{x-operation-id}}}{{/exts}}(
&self,
{{#vendorExtensions}}
{{#exts}}
{{#x-callback-params}}
callback_{{.}}: String,
{{/x-callback-params}}
{{/vendorExtensions}}
{{/exts}}
{{#allParams}}
param_{{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}},
{{/allParams}}
@ -15,20 +15,20 @@
#[allow(clippy::uninlined_format_args)]
let mut uri = format!(
{{#isCallbackRequest}}
"{{vendorExtensions.x-path-format-string}}"
"{{exts.x-path-format-string}}"
{{/isCallbackRequest}}
{{^isCallbackRequest}}
"{}{{^servers}}{{{basePathWithoutHost}}}{{/servers}}{{#servers.0}}{{{url}}}{{/servers.0}}{{vendorExtensions.x-path-format-string}}",
"{}{{^servers}}{{{basePathWithoutHost}}}{{/servers}}{{#servers.0}}{{{url}}}{{/servers.0}}{{exts.x-path-format-string}}",
self.base_path
{{/isCallbackRequest}}
{{#pathParams}}
,{{{paramName}}}=utf8_percent_encode(&param_{{{paramName}}}.to_string(), ID_ENCODE_SET)
{{/pathParams}}
{{#vendorExtensions}}
{{#exts}}
{{#x-callback-params}}
,{{.}}=callback_{{.}}
{{/x-callback-params}}
{{/vendorExtensions}}
{{/exts}}
);
// Query parameters
@ -39,7 +39,7 @@
if let Some(param_{{{paramName}}}) = param_{{{paramName}}} {
{{/required}}
query_string.append_pair("{{{baseName}}}",
{{#vendorExtensions}}
{{#exts}}
{{#x-consumes-json}}
&match serde_json::to_string(&param_{{{paramName}}}) {
Ok(str) => str,
@ -54,7 +54,7 @@
&param_{{{paramName}}}{{^isString}}.to_string(){{/isString}});
{{/isArray}}
{{/x-consumes-json}}
{{/vendorExtensions}}
{{/exts}}
{{^required}}
}
{{/required}}
@ -81,7 +81,7 @@
};
let mut request = match Request::builder()
.method("{{{vendorExtensions.x-http-method}}}")
.method("{{{exts.x-http-method}}}")
.uri(uri)
.body(BoxBody::new(http_body_util::Empty::new())) {
Ok(req) => req,
@ -214,7 +214,7 @@
{{>client-response-body-instance}}
Ok({{{operationId}}}Response::{{#vendorExtensions}}{{x-response-id}}{{/vendorExtensions}}
Ok({{{operationId}}}Response::{{#exts}}{{x-response-id}}{{/exts}}
{{^headers}}
(body)
{{/headers}}
@ -232,7 +232,7 @@
{{/dataType}}
{{^dataType}}
Ok(
{{{operationId}}}Response::{{#vendorExtensions}}{{x-response-id}}{{/vendorExtensions}}
{{{operationId}}}Response::{{#exts}}{{x-response-id}}{{/exts}}
{{#headers}}
{{#-first}}
{

View File

@ -1,4 +1,4 @@
{{#vendorExtensions}}
{{#exts}}
{{#x-consumes-multipart-form}}
// Consumes multipart/form body
@ -42,7 +42,7 @@
#[allow(clippy::uninlined_format_args)]
params.push(("{{{baseName}}}",
{{^isString}}
format!("{{{vendorExtensions.x-format-string}}}", param_{{{paramName}}})
format!("{{{exts.x-format-string}}}", param_{{{paramName}}})
{{/isString}}
{{#isString}}
{{#isArray}}
@ -78,7 +78,7 @@
{{^required}}
if let Some(param_{{{paramName}}}) = param_{{{paramName}}} {
{{/required}}
{{#vendorExtensions}}
{{#exts}}
{{#x-consumes-plain-text}}
{{#isByteArray}}
let body = String::from_utf8(param_body.0).expect("Body was not valid UTF8");
@ -93,7 +93,7 @@
{{#x-consumes-json}}
let body = serde_json::to_string(&param_{{{paramName}}}).expect("impossible to fail to serialize");
{{/x-consumes-json}}
{{/vendorExtensions}}
{{/exts}}
*request.body_mut() = body_from_string(body);
{{^required}}
}
@ -103,4 +103,4 @@
request.headers_mut().insert(CONTENT_TYPE, HeaderValue::from_static(header));
{{/bodyParam}}
{{/x-consumes-basic}}
{{/vendorExtensions}}
{{/exts}}

View File

@ -1,7 +1,7 @@
let (body_string, multipart_header) = {
let mut multipart = Multipart::new();
{{#vendorExtensions}}
{{#exts}}
{{#formParams}}
{{#-first}}
// For each parameter, encode as appropriate and add to the multipart body as a stream.
@ -36,7 +36,7 @@
multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, filename, Some({{{paramName}}}_mime));
{{/isByteArray}}
{{/formParams}}
{{/vendorExtensions}}
{{/exts}}
let mut fields = match multipart.prepare() {
Ok(fields) => fields,

View File

@ -1,4 +1,4 @@
{{#vendorExtensions}}
{{#exts}}
{{#x-produces-bytes}}
let body = swagger::ByteArray(body.to_vec());
{{/x-produces-bytes}}
@ -19,4 +19,4 @@
let body = body.to_string();
{{/x-produces-plain-text}}
{{/x-produces-bytes}}
{{/vendorExtensions}}
{{/exts}}

View File

@ -67,10 +67,10 @@ let param_{{{paramName}}} = match param_{{{paramName}}} {
};
{{/required}}
{{/formParams}}
{{^vendorExtensions.x-consumes-basic}}
{{^exts.x-consumes-basic}}
let body = {{{dataType}}} {
{{#formParams}}
{{{paramName}}}: param_{{{paramName}}},
{{/formParams}}
};
{{/vendorExtensions.x-consumes-basic}}
{{/exts.x-consumes-basic}}

View File

@ -142,7 +142,7 @@ impl<T, A, B, C, ReqBody> Service<Request<ReqBody>> for AddContext<T, A>
{
use swagger::auth::api_key_from_header;
if let Some(header) = api_key_from_header(headers, "{{vendorExtensions.x-key-param-name-lower}}") {
if let Some(header) = api_key_from_header(headers, "{{exts.x-key-param-name-lower}}") {
let auth_data = AuthData::ApiKey(header);
let context = context.push(Some(auth_data));

View File

@ -140,24 +140,24 @@ fn main() {
{{#apis}}
{{#operations}}
{{#operation}}
{{#vendorExtensions}}
{{#exts}}
{{#x-no-client-example}}
/* Disabled because there's no example.
{{/x-no-client-example}}
{{/vendorExtensions}}
{{/exts}}
Some("{{{operationId}}}") => {
let result = rt.block_on(client.{{{vendorExtensions.x-operation-id}}}(
let result = rt.block_on(client.{{{exts.x-operation-id}}}(
{{#allParams}}
{{{vendorExtensions.x-example}}}{{^-last}},{{/-last}}
{{{exts.x-example}}}{{^-last}},{{/-last}}
{{/allParams}}
));
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
},
{{#vendorExtensions}}
{{#exts}}
{{#x-no-client-example}}
*/
{{/x-no-client-example}}
{{/vendorExtensions}}
{{/exts}}
{{/operation}}
{{/operations}}
{{/apis}}

View File

@ -1,18 +1,18 @@
{{#summary}}
/// {{{.}}}
{{/summary}}
async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}(
async fn {{#exts}}{{{x-operation-id}}}{{/exts}}(
&self,
{{#vendorExtensions}}
{{#exts}}
{{#x-callback-params}}
callback_{{.}}: String,
{{/x-callback-params}}
{{/vendorExtensions}}
{{/exts}}
{{#allParams}}
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}},
{{/allParams}}
context: &C) -> Result<{{{operationId}}}Response, ApiError>
{
info!("{{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}({{#allParams}}{{#vendorExtensions}}{{{x-format-string}}}{{/vendorExtensions}}{{^-last}}, {{/-last}}{{/allParams}}) - X-Span-ID: {:?}"{{#allParams}}, {{{paramName}}}{{/allParams}}, context.get().0.clone());
info!("{{#exts}}{{{x-operation-id}}}{{/exts}}({{#allParams}}{{#exts}}{{{x-format-string}}}{{/exts}}{{^-last}}, {{/-last}}{{/allParams}}) - X-Span-ID: {:?}"{{#allParams}}, {{{paramName}}}{{/allParams}}, context.get().0.clone());
Err(ApiError("Api-Error: Operation is NOT implemented".into()))
}

View File

@ -43,7 +43,7 @@ pub trait Api<C: Send + Sync> {
{{#summary}}
/// {{{.}}}
{{/summary}}
async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}(
async fn {{#exts}}{{{x-operation-id}}}{{/exts}}(
&self,
{{#allParams}}
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}},
@ -70,7 +70,7 @@ pub trait ApiNoContext<C: Send + Sync> {
{{#summary}}
/// {{{.}}}
{{/summary}}
async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}(
async fn {{#exts}}{{{x-operation-id}}}{{/exts}}(
&self,
{{#allParams}}
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}},
@ -109,7 +109,7 @@ impl<T: Api<C> + Send + Sync, C: Clone + Send + Sync> ApiNoContext<C> for Contex
{{#summary}}
/// {{{.}}}
{{/summary}}
async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}(
async fn {{#exts}}{{{x-operation-id}}}{{/exts}}(
&self,
{{#allParams}}
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}},
@ -117,7 +117,7 @@ impl<T: Api<C> + Send + Sync, C: Clone + Send + Sync> ApiNoContext<C> for Contex
) -> Result<{{{operationId}}}Response, ApiError>
{
let context = self.context().clone();
self.api().{{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}({{#allParams}}{{{paramName}}}, {{/allParams}}&context).await
self.api().{{#exts}}{{{x-operation-id}}}{{/exts}}({{#allParams}}{{{paramName}}}, {{/allParams}}&context).await
}
{{/operation}}
@ -159,13 +159,13 @@ pub trait CallbackApi<C: Send + Sync> {
{{#summary}}
/// {{{.}}}
{{/summary}}
async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}(
async fn {{#exts}}{{{x-operation-id}}}{{/exts}}(
&self,
{{#vendorExtensions}}
{{#exts}}
{{#x-callback-params}}
callback_{{.}}: String,
{{/x-callback-params}}
{{/vendorExtensions}}
{{/exts}}
{{#allParams}}
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}},
{{/allParams}}
@ -196,13 +196,13 @@ pub trait CallbackApiNoContext<C: Send + Sync> {
{{#summary}}
/// {{{.}}}
{{/summary}}
async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}(
async fn {{#exts}}{{{x-operation-id}}}{{/exts}}(
&self,
{{#vendorExtensions}}
{{#exts}}
{{#x-callback-params}}
callback_{{.}}: String,
{{/x-callback-params}}
{{/vendorExtensions}}
{{/exts}}
{{#allParams}}
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}},
{{/allParams}}
@ -246,25 +246,25 @@ impl<T: CallbackApi<C> + Send + Sync, C: Clone + Send + Sync> CallbackApiNoConte
{{#summary}}
/// {{{.}}}
{{/summary}}
async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}(
async fn {{#exts}}{{{x-operation-id}}}{{/exts}}(
&self,
{{#vendorExtensions}}
{{#exts}}
{{#x-callback-params}}
callback_{{.}}: String,
{{/x-callback-params}}
{{/vendorExtensions}}
{{/exts}}
{{#allParams}}
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}},
{{/allParams}}
) -> Result<{{{operationId}}}Response, ApiError>
{
let context = self.context().clone();
self.api().{{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}(
{{#vendorExtensions}}
self.api().{{#exts}}{{{x-operation-id}}}{{/exts}}(
{{#exts}}
{{#x-callback-params}}
callback_{{.}},
{{/x-callback-params}}
{{/vendorExtensions}}
{{/exts}}
{{#allParams}}
{{{paramName}}},
{{/allParams}}

View File

@ -59,7 +59,7 @@ impl std::str::FromStr for {{{classname}}} {
{{/isEnum}}
{{^isEnum}}
{{#dataType}}
#[derive(Debug, Clone, PartialEq, {{#vendorExtensions.x-partial-ord}}PartialOrd, {{/vendorExtensions.x-partial-ord}}serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, PartialEq, {{#exts.x-partial-ord}}PartialOrd, {{/exts.x-partial-ord}}serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
{{#xmlName}}
#[serde(rename = "{{{.}}}")]
@ -91,8 +91,8 @@ impl std::ops::DerefMut for {{{classname}}} {
}
}
{{#vendorExtensions.x-to-string-support}}
{{#vendorExtensions.x-is-string}}
{{#exts.x-to-string-support}}
{{#exts.x-is-string}}
impl std::fmt::Display for {{{classname}}} {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0.clone())
@ -105,8 +105,8 @@ impl std::str::FromStr for {{{classname}}} {
std::result::Result::Ok({{{classname}}}(x.to_owned()))
}
}
{{/vendorExtensions.x-is-string}}
{{^vendorExtensions.x-is-string}}
{{/exts.x-is-string}}
{{^exts.x-is-string}}
/// Converts the {{{classname}}} value to the Query Parameters representation (style=form, explode=false)
/// specified in <https://swagger.io/docs/specification/serialization/>
/// Should be implemented in a serde serializer
@ -129,9 +129,9 @@ impl ::std::str::FromStr for {{{classname}}} {
}
}
}
{{/vendorExtensions.x-is-string}}
{{/vendorExtensions.x-to-string-support}}
{{^vendorExtensions.x-to-string-support}}
{{/exts.x-is-string}}
{{/exts.x-to-string-support}}
{{^exts.x-to-string-support}}
/// Converts the {{{classname}}} value to the Query Parameters representation (style=form, explode=false)
/// specified in <https://swagger.io/docs/specification/serialization/>
/// Should be implemented in a serde serializer
@ -152,11 +152,11 @@ impl ::std::str::FromStr for {{{classname}}} {
std::result::Result::Err("Parsing {{{classname}}} is not supported")
}
}
{{/vendorExtensions.x-to-string-support}}
{{/exts.x-to-string-support}}
{{/dataType}}
{{^dataType}}
{{#arrayModelType}}
{{#vendorExtensions}}{{#x-item-xml-name}}// Utility function for wrapping list elements when serializing xml
{{#exts}}{{#x-item-xml-name}}// Utility function for wrapping list elements when serializing xml
#[allow(non_snake_case)]
fn wrap_in_{{{x-item-xml-name}}}<S>(items: &Vec<{{{arrayModelType}}}>, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
@ -173,16 +173,16 @@ where
}
{{/x-item-xml-name}}
{{/vendorExtensions}}
{{/exts}}
{{! vec}}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
pub struct {{{classname}}}(
{{#vendorExtensions}}
{{#exts}}
{{#x-item-xml-name}}
#[serde(serialize_with = "wrap_in_{{{x-item-xml-name}}}")]
{{/x-item-xml-name}}
{{/vendorExtensions}}
{{/exts}}
Vec<{{{arrayModelType}}}>
);
@ -282,11 +282,11 @@ pub struct {{{classname}}} {
{{/description}}{{#isEnum}} // Note: inline enums are not fully supported by openapi-generator
{{/isEnum}}
#[serde(rename = "{{{baseName}}}")]
{{#vendorExtensions}}
{{#exts}}
{{#x-item-xml-name}}
#[serde(serialize_with = "wrap_in_{{{x-item-xml-name}}}")]
{{/x-item-xml-name}}
{{/vendorExtensions}}
{{/exts}}
{{#hasValidation}}
#[validate(
{{#maxLength}}

View File

@ -1,14 +1,14 @@
#[derive(Debug, PartialEq, Serialize, Deserialize)]
{{#vendorExtensions.x-must-use-response}}
{{#exts.x-must-use-response}}
#[must_use]
{{/vendorExtensions.x-must-use-response}}
{{/exts.x-must-use-response}}
pub enum {{{operationId}}}Response {
{{#responses}}
{{#message}}
/// {{{.}}}{{/message}}
{{#vendorExtensions}}
{{#exts}}
{{{x-response-id}}}
{{/vendorExtensions}}
{{/exts}}
{{^dataType}}
{{#hasHeaders}}
{
@ -16,25 +16,25 @@ pub enum {{{operationId}}}Response {
{{/dataType}}
{{#dataType}}
{{^hasHeaders}}
{{#vendorExtensions}}
{{#exts}}
{{#x-produces-plain-text}}
(String)
{{/x-produces-plain-text}}
{{^x-produces-plain-text}}
({{{dataType}}})
{{/x-produces-plain-text}}
{{/vendorExtensions}}
{{/exts}}
{{/hasHeaders}}
{{#hasHeaders}}
{
{{#vendorExtensions}}
{{#exts}}
{{#x-produces-plain-text}}
body: String,
{{/x-produces-plain-text}}
{{^x-produces-plain-text}}
body: {{{dataType}}},
{{/x-produces-plain-text}}
{{/vendorExtensions}}
{{/exts}}
{{/hasHeaders}}
{{/dataType}}
{{#headers}}

View File

@ -41,7 +41,7 @@ impl<T> RequestParser<T> for ApiRequestParser {
{{#operations}}
{{#operation}}
// {{{operationId}}} - {{{httpMethod}}} {{{path}}}
hyper::Method::{{{vendorExtensions.x-http-method}}} if path.matched(paths::ID_{{{vendorExtensions.x-path-id}}}) => Some("{{{operationId}}}"),
hyper::Method::{{{exts.x-http-method}}} if path.matched(paths::ID_{{{exts.x-path-id}}}) => Some("{{{operationId}}}"),
{{/operation}}
{{/operations}}
{{/apis}}

View File

@ -1,5 +1,5 @@
// {{{operationId}}} - {{{httpMethod}}} {{{path}}}
hyper::Method::{{vendorExtensions.x-http-method}} if path.matched(paths::ID_{{vendorExtensions.x-path-id}}) => {
hyper::Method::{{exts.x-http-method}} if path.matched(paths::ID_{{exts.x-path-id}}) => {
{{#hasAuthMethods}}
{
let authorization = match *(&context as &dyn Has<Option<Authorization>>).get() {
@ -37,7 +37,7 @@
}
{{/hasAuthMethods}}
{{#vendorExtensions}}
{{#exts}}
{{#x-has-path-params}}
// Path parameters
let path: &str = uri.path();
@ -49,7 +49,7 @@
);
{{/x-has-path-params}}
{{/vendorExtensions}}
{{/exts}}
{{#pathParams}}
let param_{{{paramName}}} = match percent_encoding::percent_decode(path_params["{{{baseName}}}"].as_bytes()).decode_utf8() {
Ok(param_{{{paramName}}}) => match param_{{{paramName}}}.parse::<{{{dataType}}}>() {
@ -66,11 +66,11 @@
};
{{/pathParams}}
{{#vendorExtensions}}
{{#exts}}
{{#x-callback-params}}
let callback_{{.}} = path_params["{{{.}}}"].to_string();
{{/x-callback-params}}
{{/vendorExtensions}}
{{/exts}}
{{#headerParams}}
{{#-first}}
// Header parameters
@ -117,7 +117,7 @@
{{/-first}}
let param_{{{paramName}}} = query_params.iter().filter(|e| e.0 == "{{{baseName}}}").map(|e| e.1.clone())
{{#isArray}}
{{^vendorExtensions.x-consumes-json}}
{{^exts.x-consumes-json}}
.filter_map(|param_{{{paramName}}}| param_{{{paramName}}}.parse().ok())
.collect::<Vec<_>>();
{{^required}}
@ -127,8 +127,8 @@
None
};
{{/required}}
{{/vendorExtensions.x-consumes-json}}
{{#vendorExtensions.x-consumes-json}}
{{/exts.x-consumes-json}}
{{#exts.x-consumes-json}}
.next();
let param_{{{paramName}}} = match param_{{{paramName}}} {
Some(param_{{{paramName}}}) => {
@ -154,19 +154,19 @@
.expect("Unable to create Bad Request response for missing query parameter {{{baseName}}}")),
};
{{/required}}
{{/vendorExtensions.x-consumes-json}}
{{/exts.x-consumes-json}}
{{/isArray}}
{{^isArray}}
.next();
let param_{{{paramName}}} = match param_{{{paramName}}} {
Some(param_{{{paramName}}}) => {
let param_{{{paramName}}} =
{{#vendorExtensions.x-consumes-json}}
{{#exts.x-consumes-json}}
serde_json::from_str::<{{{dataType}}}>
{{/vendorExtensions.x-consumes-json}}
{{^vendorExtensions.x-consumes-json}}
{{/exts.x-consumes-json}}
{{^exts.x-consumes-json}}
<{{{dataType}}} as std::str::FromStr>::from_str
{{/vendorExtensions.x-consumes-json}}
{{/exts.x-consumes-json}}
(&param_{{{paramName}}});
match param_{{{paramName}}} {
Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}),
@ -192,29 +192,29 @@
{{/-last}}
{{/queryParams}}
{{#vendorExtensions.x-has-request-body}}
{{#exts.x-has-request-body}}
// Handle body parameters (note that non-required body parameters will ignore garbage
// values, rather than causing a 400 response). Produce warning header and logs for
// any unused fields.
let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec());
match result {
Ok(body) => {
{{^vendorExtensions.x-consumes-multipart-form}}
{{^vendorExtensions.x-consumes-form}}
{{^bodyParam.vendorExtensions.x-consumes-plain-text}}
{{^exts.x-consumes-multipart-form}}
{{^exts.x-consumes-form}}
{{^bodyParam.exts.x-consumes-plain-text}}
let mut unused_elements : Vec<String> = vec![];
{{/bodyParam.vendorExtensions.x-consumes-plain-text}}
{{/vendorExtensions.x-consumes-form}}
{{/vendorExtensions.x-consumes-multipart-form}}
{{/bodyParam.exts.x-consumes-plain-text}}
{{/exts.x-consumes-form}}
{{/exts.x-consumes-multipart-form}}
{{>server-request-body-instance}}
{{/vendorExtensions.x-has-request-body}}
let result = api_impl.{{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}(
{{#vendorExtensions}}
{{/exts.x-has-request-body}}
let result = api_impl.{{#exts}}{{{x-operation-id}}}{{/exts}}(
{{#exts}}
{{#x-callback-params}}
callback_{{.}},
{{/x-callback-params}}
{{/vendorExtensions}}
{{/exts}}
{{#allParams}}
param_{{{paramName}}}{{#isArray}}.as_ref(){{/isArray}},
{{/allParams}}
@ -226,24 +226,24 @@
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().as_str())
.expect("Unable to create X-Span-ID header value"));
{{#vendorExtensions.x-has-request-body}}
{{^vendorExtensions.x-consumes-multipart-form}}
{{^vendorExtensions.x-consumes-form}}
{{^bodyParam.vendorExtensions.x-consumes-plain-text}}
{{#exts.x-has-request-body}}
{{^exts.x-consumes-multipart-form}}
{{^exts.x-consumes-form}}
{{^bodyParam.exts.x-consumes-plain-text}}
if !unused_elements.is_empty() {
response.headers_mut().insert(
HeaderName::from_static("warning"),
HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str())
.expect("Unable to create Warning header value"));
}
{{/bodyParam.vendorExtensions.x-consumes-plain-text}}
{{/vendorExtensions.x-consumes-form}}
{{/vendorExtensions.x-consumes-multipart-form}}
{{/vendorExtensions.x-has-request-body}}
{{/bodyParam.exts.x-consumes-plain-text}}
{{/exts.x-consumes-form}}
{{/exts.x-consumes-multipart-form}}
{{/exts.x-has-request-body}}
match result {
Ok(rsp) => match rsp {
{{#responses}}
{{{operationId}}}Response::{{#vendorExtensions}}{{x-response-id}}{{/vendorExtensions}}
{{{operationId}}}Response::{{#exts}}{{x-response-id}}{{/exts}}
{{#dataType}}
{{^headers}}
(body)
@ -309,12 +309,12 @@
}
Ok(response)
{{#vendorExtensions.x-has-request-body}}
{{#exts.x-has-request-body}}
},
Err(e) => Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(body_from_string(format!("Unable to read body: {}", e.into())))
.expect("Unable to create Bad Request response due to unable to read body")),
}
{{/vendorExtensions.x-has-request-body}}
{{/exts.x-has-request-body}}
},

View File

@ -1,4 +1,4 @@
{{#vendorExtensions}}
{{#exts}}
let param_{{{paramName}}}: Option<{{{dataType}}}> = if !body.is_empty() {
{{#x-consumes-xml}}
let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body);
@ -41,7 +41,7 @@
}
{{/isString}}
{{/x-consumes-plain-text}}
{{/vendorExtensions}}
{{/exts}}
} else {
None
};

View File

@ -1,13 +1,13 @@
{{#vendorExtensions}}
{{#exts}}
{{#formParams}}
{{#-first}}
// Form parameters
{{/-first}}
let param_{{{paramName}}} =
{{^isContainer}}
{{#vendorExtensions}}
{{#exts}}
{{{x-example}}};
{{/vendorExtensions}}
{{/exts}}
{{/isContainer}}
{{#isArray}}
{{#required}}
@ -21,4 +21,4 @@
None;
{{/isMap}}
{{/formParams}}
{{/vendorExtensions}}
{{/exts}}

View File

@ -1,4 +1,4 @@
{{#vendorExtensions}}
{{#exts}}
{{#x-consumes-multipart}}
{{#x-consumes-multipart-related}}
{{>server-request-body-multipart-related}}
@ -21,4 +21,4 @@
{{/bodyParams}}
{{/x-consumes-multipart}}
{{/vendorExtensions}}
{{/exts}}

View File

@ -1,5 +1,5 @@
{{#dataType}}
{{#vendorExtensions}}
{{#exts}}
{{^x-produces-multipart-related}}
response.headers_mut().insert(
CONTENT_TYPE,
@ -43,6 +43,6 @@
.expect("Unable to create Content-Type header for multipart/related"));
{{/formParams}}
{{/x-produces-multipart-related}}
{{/vendorExtensions}}
{{/exts}}
*response.body_mut() = body_from_string(body);
{{/dataType}}