Use Array for serialized param instead of Set

A serializable query parameter of Array type should be mapped to Array
instead of Set (use set when uniqueItems = true)

Change-Id: I410186281969360da2ce854b288e227fc1425d6c
This commit is contained in:
Artem Goncharov
2024-11-18 20:39:57 +01:00
parent f1194e369d
commit d02ace52ab
3 changed files with 23 additions and 11 deletions

View File

@@ -90,6 +90,7 @@ class ParameterSchema(BaseModel):
deprecated: bool = False
style: str | None = None
explode: bool | None = None
uniqueItems: bool | None = None
ref: str = Field(alias="$ref", default=None)
openstack: Dict[str, Any] = Field(alias="x-openstack", default=None)

View File

@@ -764,7 +764,10 @@ class OpenAPISchemaParser(JsonSchemaParser):
if style == "form" and not explode:
dt = CommaSeparatedList(item_type=ConstraintString())
elif style == "form" and explode:
dt = Set(item_type=ConstraintString())
if not param_schema.get("uniqueItems", False):
dt = Array(item_type=ConstraintString())
else:
dt = Set(item_type=ConstraintString())
else:
raise NotImplementedError(
f"Parameter serialization {schema} not supported"

View File

@@ -166,18 +166,28 @@ impl{{ type_manager.get_request_static_lifetimes(request) }} RestEndpoint for Re
{%- if type_manager.parameters.values()|selectattr("location", "equalto", "query")|list|length > 0 %}
let mut params = QueryParams::default();
{%- for param in type_manager.parameters.values() %}
{%- if param.location == "query" %}
{%- for param in type_manager.parameters.values() %}
{%- if param.location == "query" %}
{%- if param.data_type.__class__.__name__ == "Null" %}
params.push_opt_key_only(
"{{ param.remote_name }}",
self.{{ param.local_name }}.as_ref()
);
{%- elif not param.type_hint.startswith("BTreeSet") %}
{%- if param.is_required %}
params.push(
{%- elif param.data_type.__class__.__name__ == "Array" %}
{%- if not param.is_required %}
if let Some(val) = &self.{{ param.local_name }} {
params.extend(val.iter().map(|value| ("{{ param.remote_name }}", value)));
}
{%- else %}
params.push_opt(
params.extend(self.{{ param.local_name }}.iter().map(|value| ("{{ param.remote_name }}", value)));
{%- endif %}
{%- elif param.type_hint.startswith("BTreeSet") %}
params.extend(self.{{ param.local_name }}.iter().map(|value| ("{{ param.remote_name }}", value)));
{%- else %}
{%- if param.is_required %}
params.push(
{%- else %}
params.push_opt(
{%- endif %}
"{{ param.remote_name }}",
self.{{ param.local_name}}
@@ -185,11 +195,9 @@ impl{{ type_manager.get_request_static_lifetimes(request) }} RestEndpoint for Re
.as_ref()
{%- endif %}
);
{%- else %}
params.extend(self.{{ param.local_name }}.iter().map(|value| ("{{ param.remote_name }}", value)));
{%- endif %}
{%- endif %}
{%- endfor %}
{%- endif %}
{%- endfor %}
params
{%- else %}