diff --git a/.generator/src/generator/cli.py b/.generator/src/generator/cli.py
index 0bd37c1ae..d2547f629 100644
--- a/.generator/src/generator/cli.py
+++ b/.generator/src/generator/cli.py
@@ -47,6 +47,7 @@ def cli(specs, output):
env.filters["untitle_case"] = formatter.untitle_case
env.filters["upperfirst"] = utils.upperfirst
env.filters["variable_name"] = formatter.variable_name
+ env.filters["has_optional_parameter"] = openapi.has_optional_parameter
env.globals["enumerate"] = enumerate
env.globals["responses_by_types"] = openapi.responses_by_types
diff --git a/.generator/src/generator/openapi.py b/.generator/src/generator/openapi.py
index 23f0ebffe..0bf8565bc 100644
--- a/.generator/src/generator/openapi.py
+++ b/.generator/src/generator/openapi.py
@@ -35,7 +35,6 @@ def option_wrapper(name, option, nullable):
def type_to_rust(schema, alternative_name=None, render_nullable=False, render_option=True, render_box=False, version=None):
"""Return Rust type name for the type."""
-
# special case for additionalProperties: true
if schema is True or schema == {}:
return "serde_json::Value"
@@ -90,17 +89,21 @@ def get_type_for_attribute(schema, attribute, current_name=None):
return type_to_rust(child_schema, alternative_name=alternative_name)
-def get_type_for_parameter(parameter, version=None):
+def get_type_for_parameter(parameter, version=None, render_option=None):
"""Return Rust type name for the parameter."""
- render_option = True
- if "required" in parameter:
- render_option = not parameter["required"]
+ if render_option is None:
+ render_option = not parameter.get("required")
if "content" in parameter:
assert "in" not in parameter
for content in parameter["content"].values():
return type_to_rust(content["schema"], version=version, render_option=render_option)
return type_to_rust(parameter.get("schema"), version=version, render_option=render_option)
+def has_optional_parameter(operation):
+ for _, parameter in parameters(operation):
+ if not parameter.get("required"):
+ return True
+ return False
def get_type_for_response(response, version):
"""Return Rust type name for the response."""
diff --git a/.generator/src/generator/templates/api.j2 b/.generator/src/generator/templates/api.j2
index 706e6a900..32e710cd1 100644
--- a/.generator/src/generator/templates/api.j2
+++ b/.generator/src/generator/templates/api.j2
@@ -4,33 +4,48 @@ use serde::{Serialize, Deserialize};
use crate::datadog::*;
{%- set structName = name.replace(" ", "")+"API" %}
-{% for path, method, operation in operations|sort(attribute="2.operationId", case_sensitive=True) %}
+{% for path, method, operation in operations|sort(attribute="2.operationId", case_sensitive=true) %}
{%- set httpMethod = method.upper() %}
{%- set returnType = operation|return_type(version) %}
{%- set formParameter = operation|form_parameter %}
-{%- set optionalBody = False if "required" in operation.requestBody and operation.requestBody.required else True %}
+{%- set optionalBody = false if "required" in operation.requestBody and operation.requestBody.required else true %}
+{%- set optionalParams = operation|parameters|rejectattr('1.required', 'equalto', true) | list %}
-{%- for name, parameter in operation|parameters %}
+{%- for name, parameter in optionalParams %}
{%- if loop.first %}
-/// {{ operation.operationId }}Params is a struct for passing parameters to the method [`{{ structName }}::{{operation.operationId | snake_case}}`]
-#[derive(Clone, Debug)]
-pub struct {{operation.operationId}}Params {
+/// {{operation.operationId}}OptionalParams is a struct for passing parameters to the method [`{{ structName }}::{{operation.operationId | snake_case}}`]
+#[derive(Clone, Default, Debug)]
+pub struct {{operation.operationId}}OptionalParams {
{%- endif %}
{%- if parameter.description is defined %}
{{parameter.description | block_comment}}
{%- endif %}
- {%- if optionalBody and name == operation.get("x-codegen-request-body-name", "body") %}
- pub {{name|variable_name}}: Option<{{ get_type_for_parameter(parameter, version) }}>,
- {%- else %}
pub {{name|variable_name}}: {{ get_type_for_parameter(parameter, version) }},
+{%- if loop.last %}
+}
+{% endif %}
+{%- endfor %}
+{%- for name, parameter in optionalParams %}
+{%- if loop.first %}
+impl {{operation.operationId}}OptionalParams {
+{%- endif %}
+ {%- if parameter.description is defined %}
+ {{parameter.description | block_comment}}
+ {%- endif %}
+ {%- if get_deprecated(model) %}
+ #[allow(deprecated)]
{%- endif %}
+ pub fn {{name|variable_name}}(&mut self, value: {{get_type_for_parameter(parameter, version, render_option=false)}}) -> &mut Self {
+ self.{{name|variable_name}} = Some(value);
+ self
+ }
{%- if loop.last %}
}
{% endif %}
{%- endfor %}
{%- endfor %}
-{% for path, method, operation in operations|sort(attribute="2.operationId", case_sensitive=True) %}
+{% for path, method, operation in operations|sort(attribute="2.operationId", case_sensitive=true) %}
{%- set httpMethod = method.upper() %}
{%- set returnType = operation|return_type(version) %}
{%- set formParameter = operation|form_parameter %}
@@ -69,15 +84,16 @@ impl {{ structName }} {
Self { config }
}
- {% for path, method, operation in operations|sort(attribute="2.operationId", case_sensitive=True) %}
+ {% for path, method, operation in operations|sort(attribute="2.operationId", case_sensitive=true) %}
{%- set httpMethod = method.upper() %}
{%- set returnType = operation|return_type(version) %}
{%- set formParameter = operation|form_parameter %}
+ {%- set requiredParams = operation|parameters|selectattr('1.required', 'equalto', true) | list %}
{% if operation.description is defined %}
{{ operation.description | block_comment }}
{%- endif %}
- pub async fn {{operation.operationId | snake_case}}(&self{% for name, parameter in operation|parameters %}{% if loop.first %}, params: {{operation.operationId}}Params{% endif %}{% endfor %}) -> Result