diff --git a/codegenerator/common/rust.py b/codegenerator/common/rust.py index 161917b..843a42e 100644 --- a/codegenerator/common/rust.py +++ b/codegenerator/common/rust.py @@ -378,6 +378,10 @@ class StructFieldResponse(StructField): @property def serde_macros(self): macros = set() + try: + macros.update(self.data_type.get_serde_macros(self.is_optional)) + except Exception: + pass if self.local_name != self.remote_name: macros.add(f'rename="{self.remote_name}"') if len(macros) > 0: @@ -429,13 +433,10 @@ class StructFieldResponse(StructField): and "status" not in struct.fields.keys() ): macros.add("status") - if self.data_type.type_hint in [ - "Value", - "Option", - "Vec", - "Option>", - ]: - macros.add("pretty") + if not isinstance(self.data_type, BasePrimitiveType) or isinstance( + self.data_type, JsonValue + ): + macros.add("serialize") return f"#[structable({', '.join(sorted(macros))})]" diff --git a/codegenerator/rust_types.py b/codegenerator/rust_types.py index b924094..2215fb4 100644 --- a/codegenerator/rust_types.py +++ b/codegenerator/rust_types.py @@ -29,25 +29,49 @@ from codegenerator.common import rust as common_rust class IntString(common.BasePrimitiveType): """CLI Integer or String""" - imports: set[str] = {"crate::common::IntString"} - type_hint: str = "IntString" + type_hint: str = "i64" + imports: set[str] = { + "crate::common::deser_num_str", + "crate::common::deser_num_str_opt", + } clap_macros: set[str] = set() + serde_macros: set[str] = {'deserialize_with="deser_num_str"'} + + def get_serde_macros(self, optional: bool = False) -> set[str]: + deser: str = "deser_num_str" if not optional else "deser_num_str_opt" + return {f'deserialize_with="{deser}"'} class NumString(common.BasePrimitiveType): """CLI Number or String""" - imports: set[str] = {"crate::common::NumString"} - type_hint: str = "NumString" + type_hint: str = "f64" + imports: set[str] = { + "crate::common::deser_num_str", + "crate::common::deser_num_str_opt", + } clap_macros: set[str] = set() + serde_macros: set[str] = {'deserialize_with="deser_num_str"'} + + def get_serde_macros(self, optional: bool = False) -> set[str]: + deser: str = "deser_num_str" if not optional else "deser_num_str_opt" + return {f'deserialize_with="{deser}"'} class BoolString(common.BasePrimitiveType): """CLI Boolean or String""" - imports: set[str] = {"crate::common::BoolString"} - type_hint: str = "BoolString" + type_hint: str = "bool" + imports: set[str] = { + "crate::common::deser_bool_str", + "crate::common::deser_bool_str_opt", + } clap_macros: set[str] = set() + serde_macros: set[str] = {'deserialize_with="deser_bool_str"'} + + def get_serde_macros(self, optional: bool = False) -> set[str]: + deser: str = "deser_bool_str" if not optional else "deser_bool_str_opt" + return {f'deserialize_with="{deser}"'} class Enum(common_rust.Enum): diff --git a/codegenerator/templates/rust_types/impl.rs.j2 b/codegenerator/templates/rust_types/impl.rs.j2 index 4774d17..9dea9c4 100644 --- a/codegenerator/templates/rust_types/impl.rs.j2 +++ b/codegenerator/templates/rust_types/impl.rs.j2 @@ -18,15 +18,17 @@ //! Response type for the {{ method }} {{ url }} operation use serde::{Deserialize, Serialize}; +use structable_derive::StructTable; {% for mod in additional_imports | sort -%} use {{ mod }}; {% endfor %} +use crate::common::{StructTable, OutputConfig}; {% with data_type = response_type_manager.get_root_data_type() %} {%- if data_type.__class__.__name__ == "StructResponse" %} {%- if data_type.fields %} /// {{ target_class_name }} response representation - #[derive(Clone, Deserialize, Serialize)] + #[derive(Clone, Deserialize, Serialize, StructTable)] pub struct {{ data_type.name }} { {%- for k, v in data_type.fields | dictsort %} {% if not (operation_type == "list" and k in ["links"]) %} @@ -34,6 +36,7 @@ use {{ mod }}; {% if v.serde_macros -%} {{ v.serde_macros }} {% endif -%} + {{ v.get_structable_macros(data_type, sdk_service_name, resource_name, operation_type) }} pub {{ v.local_name }}: {{ v.type_hint }}, {%- endif %} {%- endfor %} @@ -46,8 +49,7 @@ use {{ mod }}; {%- elif data_type.__class__.__name__ == "TupleStruct" %} {#- tuple struct requires custom implementation of StructTable #} /// {{ target_class_name }} response representation - #[derive(Deserialize, Serialize)] - #[derive(Clone)] + #[derive(Clone, Deserialize, Serialize)] pub struct {{ class_name }}( {%- for field in data_type.tuple_fields %} {{ field.type_hint }},