Skip to content

Commit

Permalink
[openapi] Add explode attribute for the operation parameter. #367
Browse files Browse the repository at this point in the history
  • Loading branch information
sunli829 committed Aug 16, 2022
1 parent d8e43b1 commit da97bd7
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 64 deletions.
7 changes: 7 additions & 0 deletions poem-openapi-derive/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ struct APIOperationParam {
default: Option<DefaultValue>,
#[darling(default)]
validator: Option<Validators>,
#[darling(default)]
explode: Option<bool>,

// for oauth
#[darling(multiple, default, rename = "scope")]
Expand Down Expand Up @@ -310,10 +312,13 @@ fn generate_operation(
let validators_update_meta = validator.create_update_meta(crate_name)?;

// do extract
let explode = operation_param.explode.unwrap_or(true);

parse_args.push(quote! {
let mut param_opts = #crate_name::ExtractParamOptions {
name: #param_name,
default_value: #default_value,
explode: #explode,
};

let #pname = match <#arg_ty as #crate_name::ApiExtractor>::from_request(&request, &mut body, param_opts).await {
Expand Down Expand Up @@ -349,6 +354,7 @@ fn generate_operation(
description: #param_desc,
required: <#arg_ty as #crate_name::ApiExtractor>::PARAM_IS_REQUIRED && !#has_default,
deprecated: #deprecated,
explode: #explode,
};
params.push(meta_param);
}
Expand Down Expand Up @@ -471,6 +477,7 @@ fn generate_operation(
description: #description,
required: <#ty as #crate_name::types::Type>::IS_REQUIRED,
deprecated: #deprecated,
explode: true,
});
});
}
Expand Down
5 changes: 5 additions & 0 deletions poem-openapi-derive/src/webhook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ struct WebHookOperationParam {
default: Option<DefaultValue>,
#[darling(default)]
validator: Option<Validators>,
#[darling(default)]
explode: Option<bool>,
}

struct Context {
Expand Down Expand Up @@ -222,6 +224,8 @@ fn generate_operation(
.unwrap_or_else(|| arg_ident.unraw().to_string());
let param_desc = optional_literal_string(&param_description);
let deprecated = operation_param.deprecated;
let explode = operation_param.explode.unwrap_or(true);

params_meta.push(quote! {
if <#arg_ty as #crate_name::ApiExtractor>::TYPE == #crate_name::ApiExtractorType::Parameter {
let mut original_schema = <#arg_ty as #crate_name::ApiExtractor>::param_schema_ref().unwrap();
Expand All @@ -240,6 +244,7 @@ fn generate_operation(
description: #param_desc,
required: <#arg_ty as #crate_name::ApiExtractor>::PARAM_IS_REQUIRED,
deprecated: #deprecated,
explode: #explode,
};
params.push(meta_param);
}
Expand Down
4 changes: 4 additions & 0 deletions poem-openapi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

# [2.0.9] 2022-08-16

- Add `explode` attribute for the operation parameter. [#367](https://github.com/poem-web/poem/issues/367)

# [2.0.8] 2022-08-12

- Fixes [#362](https://github.com/poem-web/poem/issues/362)
Expand Down
6 changes: 6 additions & 0 deletions poem-openapi/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,19 @@ pub struct ExtractParamOptions<T> {

/// The default value of this parameter.
pub default_value: Option<fn() -> T>,

/// When this is `true`, parameter values of type array or object generate
/// separate parameters for each value of the array or key-value pair of the
/// map.
pub explode: bool,
}

impl<T> Default for ExtractParamOptions<T> {
fn default() -> Self {
Self {
name: "",
default_value: None,
explode: true,
}
}
}
Expand Down
36 changes: 19 additions & 17 deletions poem-openapi/src/docs/openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ Parameters that can be passed into the `#[oai()]` attribute above each operation
| transform | Use a function to transform the API endpoint. | string | Y |
| response_header | Add an extra response header to the operation. | [`ExtraHeader`](macro@ApiResponse#extra-header-parameters) | Y |
| request_header | Add an extra request header to all operations. | [`ExtraHeader`](macro@ApiResponse#extra-header-parameters) | Y |
| actual_type | Specifies the actual response type | Y | string |
| actual_type | Specifies the actual response type | string | Y |

## Example

```rust
Expand Down Expand Up @@ -85,22 +86,23 @@ impl Api {

# Operation argument parameters

| Attribute | Description | Type | Optional |
|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|----------|
| name | Parameter name | string | Y |
| deprecated | Argument deprecated | bool | Y |
| default | Default value | bool,string | Y |
| validator.multiple_of | The value of "multiple_of" MUST be a number, strictly greater than 0. A numeric instance is only valid if division by this value results in an integer. | number | Y |
| validator.maximum | The value of "maximum" MUST be a number, representing an upper limit for a numeric instance. If `exclusive` is `true` and instance is less than the provided value, or else if the instance is less than or exactly equal to the provided value. | { value: `<number>`, exclusive: `<bool>`} | Y |
| validator.minimum | The value of "minimum" MUST be a number, representing a lower limit for a numeric instance. If `exclusive` is `true` and instance is greater than the provided value, or else if the instance is greater than or exactly equal to the provided value. | { value: `<number>`, exclusive: `<bool>`} | Y |
| validator.max_length | The value of "max_length" MUST be a non-negative integer. A string instance is valid against this validator if its length is less than, or equal to, the value. | usize | Y |
| validator.min_length | The value of "min_length" MUST be a non-negative integer. The value of this validator MUST be an integer. This integer MUST be greater than, or equal to, 0. | usize | Y |
| validator.pattern | The value of "pattern" MUST be a string. This string SHOULD be a valid regular expression, according to the ECMA 262 regular expression dialect. A string instance is considered valid if the regular expression matches the instance successfully. | string | Y |
| validator.max_items | The value of "max_items" MUST be an integer. This integer MUST be greater than, or equal to, 0. An array instance is valid if its size is less than, or equal to, the value of this validator. | usize | Y |
| validator.min_items | The value of "min_items" MUST be an integer. This integer MUST be greater than, or equal to, 0. An array instance is valid if its size is greater than, or equal to, the value of this validator. | usize | Y |
| validator.unique_items | The value of "unique_items" MUST be an boolean. If this value is `false`, the instance validates successfully. If this value is `true`, the instance validates successfully if all of its elements are unique. | bool | Y |
| validator.max_properties | The value of this keyword MUST be a non-negative integer. An object instance is valid against "maxProperties" if its number of properties is less than, or equal to, the value of this keyword. | usize | Y |
| validator.min_properties | The value of this keyword MUST be a non-negative integer. An object instance is valid against "minProperties" if its number of properties is greater than, or equal to, the value of this keyword. | usize | Y |
| Attribute | Description | Type | Optional |
|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|-------------------|
| name | Parameter name | string | Y |
| deprecated | Argument deprecated | bool | Y |
| default | Default value | bool,string | Y |
| explode | When this is `true`, parameter values of type array or object generate separate parameters for each value of the array or key-value pair of the map. | bool | Y (default: true) |
| validator.multiple_of | The value of "multiple_of" MUST be a number, strictly greater than 0. A numeric instance is only valid if division by this value results in an integer. | number | Y |
| validator.maximum | The value of "maximum" MUST be a number, representing an upper limit for a numeric instance. If `exclusive` is `true` and instance is less than the provided value, or else if the instance is less than or exactly equal to the provided value. | { value: `<number>`, exclusive: `<bool>`} | Y |
| validator.minimum | The value of "minimum" MUST be a number, representing a lower limit for a numeric instance. If `exclusive` is `true` and instance is greater than the provided value, or else if the instance is greater than or exactly equal to the provided value. | { value: `<number>`, exclusive: `<bool>`} | Y |
| validator.max_length | The value of "max_length" MUST be a non-negative integer. A string instance is valid against this validator if its length is less than, or equal to, the value. | usize | Y |
| validator.min_length | The value of "min_length" MUST be a non-negative integer. The value of this validator MUST be an integer. This integer MUST be greater than, or equal to, 0. | usize | Y |
| validator.pattern | The value of "pattern" MUST be a string. This string SHOULD be a valid regular expression, according to the ECMA 262 regular expression dialect. A string instance is considered valid if the regular expression matches the instance successfully. | string | Y |
| validator.max_items | The value of "max_items" MUST be an integer. This integer MUST be greater than, or equal to, 0. An array instance is valid if its size is less than, or equal to, the value of this validator. | usize | Y |
| validator.min_items | The value of "min_items" MUST be an integer. This integer MUST be greater than, or equal to, 0. An array instance is valid if its size is greater than, or equal to, the value of this validator. | usize | Y |
| validator.unique_items | The value of "unique_items" MUST be an boolean. If this value is `false`, the instance validates successfully. If this value is `true`, the instance validates successfully if all of its elements are unique. | bool | Y |
| validator.max_properties | The value of this keyword MUST be a non-negative integer. An object instance is valid against "maxProperties" if its number of properties is less than, or equal to, the value of this keyword. | usize | Y |
| validator.min_properties | The value of this keyword MUST be a non-negative integer. An object instance is valid against "minProperties" if its number of properties is greater than, or equal to, the value of this keyword. | usize | Y |

# Examples

Expand Down
2 changes: 1 addition & 1 deletion poem-openapi/src/docs/response.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Define a OpenAPI response.
|--------------|--------------------------------------------------------------|------------------------------------------------------------|----------|
| status | HTTP status code. If omitted, it is a default response type. | u16 | Y |
| content_type | Specify the content type. | string | Y |
| actual_type | Specifies the actual response type | Y | string |
| actual_type | Specifies the actual response type | string | Y |
| header | Add an extra header | [`ExtraHeader`](macro@ApiResponse#extra-header-parameters) | Y |

# Header parameters
Expand Down
2 changes: 1 addition & 1 deletion poem-openapi/src/docs/response_content.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Define a OpenAPI response content.
| Attribute | Description | Type | Optional |
|--------------|------------------------------------|--------|----------|
| content_type | Specify the content type. | string | Y |
| actual_type | Specifies the actual response type | Y | string |
| actual_type | Specifies the actual response type | string | Y |

# Examples

Expand Down
Loading

0 comments on commit da97bd7

Please sign in to comment.