diff --git a/codegenerator/common/rust.py b/codegenerator/common/rust.py index a9e99b7..a291413 100644 --- a/codegenerator/common/rust.py +++ b/codegenerator/common/rust.py @@ -1364,7 +1364,9 @@ class TypeManager: for parameter in parameters: data_type = self.convert_model(parameter.data_type) param = self.request_parameter_class( - remote_name=self.get_remote_attribute_name(parameter.name), + remote_name=self.get_remote_attribute_name(parameter.name) + if parameter.location != "header" + else parameter.name, local_name=self.get_local_attribute_name(parameter.name), data_type=data_type, location=parameter.location, diff --git a/codegenerator/templates/rust_cli/headers_parameters.j2 b/codegenerator/templates/rust_cli/headers_parameters.j2 index 27aa220..c2ed2b3 100644 --- a/codegenerator/templates/rust_cli/headers_parameters.j2 +++ b/codegenerator/templates/rust_cli/headers_parameters.j2 @@ -1,4 +1,4 @@ -{%- if type_manager.get_parameters("header") %} +{%- if type_manager.get_parameters("header") | list | length > 0 %} /// Header parameters #[derive(Args)] diff --git a/codegenerator/templates/rust_cli/impl.rs.j2 b/codegenerator/templates/rust_cli/impl.rs.j2 index 859e702..84954a8 100644 --- a/codegenerator/templates/rust_cli/impl.rs.j2 +++ b/codegenerator/templates/rust_cli/impl.rs.j2 @@ -44,6 +44,13 @@ pub struct {{ target_class_name }}Command { #[command(flatten)] query: QueryParameters, +{%- if type_manager.get_parameters("header") | list | length > 0 %} + + /// Request Headers parameters + #[command(flatten)] + headers: HeaderParameters, +{%- endif %} + /// Path parameters #[command(flatten)] path: PathParameters, @@ -68,6 +75,7 @@ pub struct {{ target_class_name }}Command { } {% include "rust_cli/query_parameters.j2" %} +{% include "rust_cli/headers_parameters.j2" %} {% include "rust_cli/path_parameters.j2" %} {%- for type in type_manager.get_subtypes() %} @@ -131,8 +139,12 @@ impl {{ target_class_name }}Command { let mut find_builder = find::{{ sdk_struct_name }}::builder(); {{ macros.set_cli_path_parameters(type_manager, "find_builder", find_mode=True) }} {%- if microversion %} - find_builder.header(http::header::HeaderName::from_static("openstack-api-version"), http::header::HeaderValue::from_static("{{ "volume" if service_type == "block-storage" else service_type }} {{ microversion }}")); + find_builder.header( + http::header::HeaderName::from_static("openstack-api-version"), + http::header::HeaderValue::from_static("{{ "volume" if service_type == "block-storage" else service_type }} {{ microversion }}") + ); {%- endif %} + {% include 'rust_cli/set_headers_parameters_to_find.j2' %} let find_ep = find_builder .build() .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?; @@ -143,10 +155,14 @@ impl {{ target_class_name }}Command { {% set builder_mutable = type_manager.is_operation_supporting_params() %} let {{ "mut" if builder_mutable }} ep_builder = {{ sdk_mod_path[-1] }}::Request::builder(); {%- if microversion %} - ep_builder.header(http::header::HeaderName::from_static("openstack-api-version"), http::header::HeaderValue::from_static("{{ "volume" if service_type == "block-storage" else service_type }} {{ microversion }}")); + ep_builder.header( + http::header::HeaderName::from_static("openstack-api-version"), + http::header::HeaderValue::from_static("{{ "volume" if service_type == "block-storage" else service_type }} {{ microversion }}") + ); {%- endif %} {{ macros.set_cli_path_parameters(type_manager, "ep_builder") }} {% include 'rust_cli/set_query_parameters.j2' %} + {% include 'rust_cli/set_headers_parameters.j2' %} {% include 'rust_cli/set_body_parameters.j2' %} {%- if operation_type == "upload" and body_types|length == 1 and body_types[0] != "*/*" %} diff --git a/codegenerator/templates/rust_cli/set_body_parameters.j2 b/codegenerator/templates/rust_cli/set_body_parameters.j2 index 95621cc..cbf5c0c 100644 --- a/codegenerator/templates/rust_cli/set_body_parameters.j2 +++ b/codegenerator/templates/rust_cli/set_body_parameters.j2 @@ -1,8 +1,8 @@ {% import 'rust_macros.j2' as macros with context -%} {% if not is_json_patch -%} - // Set body parameters {%- with root = type_manager.get_root_data_type() %} -{%- if root.__class__.__name__ == "StructInput" -%} +{%- if root.__class__.__name__ == "StructInput" and root.fields -%} + // Set body parameters {%- for root_attr, root_field in root.fields | dictsort %} // Set Request.{{ root_field.remote_name }} data @@ -70,6 +70,7 @@ } {%- endif %} {%- elif root.__class__.__name__ == "DictionaryInput" %} + // Set body parameters if let Some(properties) = &self.properties { {%- if root.value_type.__class__.__name__ == "Option" %} ep_builder.properties(properties diff --git a/codegenerator/templates/rust_cli/set_headers_parameters.j2 b/codegenerator/templates/rust_cli/set_headers_parameters.j2 index 4978963..7b8ee5c 100644 --- a/codegenerator/templates/rust_cli/set_headers_parameters.j2 +++ b/codegenerator/templates/rust_cli/set_headers_parameters.j2 @@ -1,26 +1,13 @@ -{%- import 'rust_macros.j2' as macros with context -%} -{%- if type_manager.get_parameters("header") %} +{%- if type_manager.get_parameters("header") | list | length > 0 -%} // Set header parameters {%- for (k, v) in type_manager.get_parameters("header") %} - {%- if v.data_type.__class__.__name__ == "BooleanFlag" and v.data_type.original_data_type.__class__.__name__ == "Null" %} - {%- if v.is_required %} - if self.query.{{ v.local_name }} { - ep_builder.{{ v.remote_name }}(serde_json::Value::Null); - - } - {%- else %} - if let Some(true) = self.query.{{ v.local_name }} { - ep_builder.{{ v.remote_name }}(serde_json::Value::Null); - - } - {%- endif %} - {%- elif not v.is_required %} - if let Some(val) = &self.query.{{ v.local_name }} { - {{ macros.set_request_data_from_input(type_manager, "ep_builder", v, "val")}} + {%- if not v.is_required %} + if let Some(val) = &self.headers.{{ v.local_name }} { + {{ macros.set_request_header_from_input(type_manager, "ep_builder", v, "val")}} } {%- else %} - {{ macros.set_request_data_from_input(type_manager, "ep_builder", v, "&self.query." + v.local_name )}} + {{ macros.set_request_header_from_input(type_manager, "ep_builder", v, "&self.headers." + v.local_name )}} {%- endif %} {%- endfor %} -{%- endif %} +{% endif -%} diff --git a/codegenerator/templates/rust_cli/set_headers_parameters_to_find.j2 b/codegenerator/templates/rust_cli/set_headers_parameters_to_find.j2 new file mode 100644 index 0000000..65c6054 --- /dev/null +++ b/codegenerator/templates/rust_cli/set_headers_parameters_to_find.j2 @@ -0,0 +1,13 @@ +{%- import 'rust_macros.j2' as macros with context -%} +{%- if type_manager.get_parameters("header") | list | length > 0 %} + +{%- for (k, v) in type_manager.get_parameters("header") %} + {%- if not v.is_required %} + if let Some(val) = &self.headers.{{ v.local_name }} { + {{ macros.set_request_header_from_input(type_manager, "find_builder", v, "val")}} + } + {%- else %} + {{ macros.set_request_header_from_input(type_manager, "find_builder", v, "&self.headers." + v.local_name )}} + {%- endif %} +{%- endfor %} +{%- endif %} diff --git a/codegenerator/templates/rust_cli/set_path_parameters.j2 b/codegenerator/templates/rust_cli/set_path_parameters.j2 index b4c0a48..f30e9e2 100644 --- a/codegenerator/templates/rust_cli/set_path_parameters.j2 +++ b/codegenerator/templates/rust_cli/set_path_parameters.j2 @@ -1,4 +1,5 @@ - // Set path parameters +{%- if type_manager.get_parameters("path") | list | length > 0 -%} + // Set path parameters2 {%- for (k, v) in type_manager.get_parameters("path") %} {%- if not v.is_required %} {%- if k != "project_id" %} @@ -16,3 +17,4 @@ ep_builder.{{ v.local_name }}(&self.path.{{ v.local_name }}); {%- endif %} {%- endfor %} +{%- endif %} diff --git a/codegenerator/templates/rust_cli/set_query_parameters.j2 b/codegenerator/templates/rust_cli/set_query_parameters.j2 index 6e0abda..a2d5cb3 100644 --- a/codegenerator/templates/rust_cli/set_query_parameters.j2 +++ b/codegenerator/templates/rust_cli/set_query_parameters.j2 @@ -1,4 +1,5 @@ {%- import 'rust_macros.j2' as macros with context -%} +{%- if type_manager.get_parameters("query") | list | length > 0 -%} // Set query parameters {%- for (k, v) in type_manager.get_parameters("query") %} {%- if not v.resource_link %} @@ -70,3 +71,4 @@ {%- endif %} {%- endif %} {%- endfor %} +{%- endif %} diff --git a/codegenerator/templates/rust_macros.j2 b/codegenerator/templates/rust_macros.j2 index f6e7f7e..7aaa4d3 100644 --- a/codegenerator/templates/rust_macros.j2 +++ b/codegenerator/templates/rust_macros.j2 @@ -451,7 +451,7 @@ Some({{ val }}) {%- endmacro %} {%- macro set_cli_path_parameters(type_manager, builder, find_mode=False) %} -{%- if not find_mode %} +{%- if not find_mode and type_manager.get_parameters("header") | list | length > 0 -%} // Set path parameters {%- endif %} @@ -579,3 +579,34 @@ Some({{ val }}) "{{ prefix }}{{ url }}".to_string() {%- endif %} {%- endmacro %} + + +{#- Macros to render setting Request headers from CLI input #} +{%- macro set_request_header_from_input(manager, dst_var, param, val_var, by_ref=False) %} +{%- set is_nullable = param.is_nullable if param.is_nullable is defined else False %} + {{ dst_var }}.header(http::header::HeaderName::from_static("{{ param.remote_name }}"), +{%- if param.type_hint == "Option" -%} + http::header::HeaderValue::from_static(if *val {"true"} else {"false"}) +{%- elif param.type_hint == "bool" -%} + http::header::HeaderValue::from_static(if val {"true"} else {"false"}) +{%- elif param.type_hint in ["Option", "Option", "Option", "Option"] -%} + {%- if param.is_optional is defined and not param.is_optional %} + if let Some(val) = {{ val_var }} { + {{ "*val" if not by_ref else "val.clone()" }} + } + {%- else %} + {{ ("*" + val_var) if not by_ref else (val_var + ".clone()") }} + {%- endif %} + +{%- elif param.type_hint in ["i32", "i64", "f32", "f64"] -%} + {{ val_var | replace("&", "" )}} + +{%- elif param.data_type.__class__.__name__ in ["String", "SecretString"] -%} + http::header::HeaderValue::from_str({{ val_var if not by_ref else (val_var + ".clone()")}})? + +{%- else -%} + http::header::HeaderValue::from_str({{ val_var if not by_ref else (val_var + ".clone()")}})? +{%- endif -%} +); + +{%- endmacro %} diff --git a/codegenerator/tests/unit/test_rust_cli.py b/codegenerator/tests/unit/test_rust_cli.py index dcae85a..a8923be 100644 --- a/codegenerator/tests/unit/test_rust_cli.py +++ b/codegenerator/tests/unit/test_rust_cli.py @@ -102,8 +102,6 @@ impl fooCommand { let mut ep_builder = srv::Request::builder(); - // Set path parameters - // Set query parameters // Set body parameters // Set Request.foo data