Skip to content

Commit

Permalink
Removes generating separate struct for nested sequence/scalar types
Browse files Browse the repository at this point in the history
* Modified Rust templates to consider `util_macros` when reading or
writing a nested sequence type
  • Loading branch information
desaikd committed May 29, 2024
1 parent 1f17530 commit 706e04d
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{% import "util_macros.templ" as util_macros %}

{# following macro defines an anonymous type as children class for its parent type definition #}
{% macro nested_type(target_kind_name, fields, abstract_data_type, nested_anonymous_types) -%}
#[derive(Debug, Clone, Default)]
Expand Down Expand Up @@ -29,7 +31,7 @@
abstract_data_type.value = {% if fields[0].value_type | is_built_in_type == false %}
{{ fields[0].value_type }}::read_from(reader)?;
{% else %}
reader.read_{% if fields[0].isl_type_name == "symbol" %}symbol()?.text().unwrap(){% else %}{{ fields[0].value_type | replace(from="string", to ="str") }}()?{% endif %}{% if fields[0].value_type | lower == "string" %} .to_string() {% endif %};
reader.read_{% if fields[0].isl_type_name == "symbol" %}symbol()?.text().unwrap(){% else %}{{ fields[0].value_type | lower | replace(from="string", to ="str") }}()?{% endif %}{% if fields[0].value_type | lower == "string" %} .to_string() {% endif %};
{% endif %}
{% elif abstract_data_type is object and abstract_data_type is containing("Structure") %}
reader.step_in()?;
Expand All @@ -38,7 +40,11 @@
match field_name {
{% for field in fields -%}
{% if field.value_type | is_built_in_type == false %}
"{{ field.name }}" => { abstract_data_type.{{ field.name | snake }} = {{ field.value_type }}::read_from(reader)?; }
{% if field.value_type is containing("Vec") %}
"{{ field.name }}" => { {{ util_macros::read_as_sequence(field=field) }} }
{% else %}
"{{ field.name }}" => { abstract_data_type.{{ field.name | snake }} = {{ field.value_type }}::read_from(reader)?; }
{% endif %}
{% else %}
"{{ field.name }}" => { abstract_data_type.{{ field.name | snake}} = reader.read_{% if field.isl_type_name == "symbol" %}symbol()?.text().unwrap(){% else %}{{ field.value_type | lower | replace(from="string", to ="str") }}()?{% endif %}{% if field.value_type | lower== "string" %} .to_string() {% endif %}; }
{% endif %}
Expand Down Expand Up @@ -95,15 +101,19 @@
{% if field.value_type | is_built_in_type == false %}
self.{{ field.name | snake }}.write_to(writer)?;
{% else %}
writer.write_{% if field.isl_type_name == "symbol" %}symbol{% else %}{{ field.value_type | lower }}{% endif %}(self.value)?;
writer.write_{% if field.isl_type_name == "symbol" %}symbol{% else %}{{ field.value_type | lower }}{% endif %}(self.value.to_owned())?;
{% endif %}
{% endfor %}
{% elif abstract_data_type is object and abstract_data_type is containing("Structure") %}
writer.step_in(IonType::Struct)?;
{% for field in fields %}
writer.set_field_name("{{ field.name }}");
{% if field.value_type | is_built_in_type == false %}
self.{{ field.name | snake }}.write_to(writer)?;
{% if field.value_type is containing("Vec") %}
{{ util_macros::write_as_sequence(field=field) }}
{% else %}
self.{{ field.name | snake }}.write_to(writer)?;
{% endif %}
{% else %}
{# TODO: Change the following `to_owned` to only be used when writing i64,f32,f64,bool which require owned value as input #}
writer.write_{% if field.isl_type_name == "symbol" %}symbol{% else %}{{ field.value_type | lower }}{% endif %}(self.{{ field.name | snake }}.to_owned())?;
Expand Down
18 changes: 14 additions & 4 deletions src/bin/ion/commands/beta/generate/templates/rust/struct.templ
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{# Includes the macros for anonymous types that will be added as child classes #}
{% import "nested_type.templ" as macros %}
{% import "util_macros.templ" as util_macros %}

use {{ target_kind_name | snake }}::{{ target_kind_name }};
pub mod {{ target_kind_name | snake }} {
use super::*;
Expand Down Expand Up @@ -33,7 +35,7 @@ pub mod {{ target_kind_name | snake }} {
abstract_data_type.value = {% if fields[0].value_type | is_built_in_type == false %}
{{ fields[0].value_type }}::read_from(reader)?;
{% else %}
reader.read_{% if fields[0].isl_type_name == "symbol" %}symbol()?.text().unwrap(){% else %}{{ fields[0].value_type | replace(from="string", to ="str") }}()?{% endif %}{% if fields[0].value_type | lower == "string" %} .to_string() {% endif %};
reader.read_{% if fields[0].isl_type_name == "symbol" %}symbol()?.text().unwrap(){% else %}{{ fields[0].value_type | lower | replace(from="string", to ="str") }}()?{% endif %}{% if fields[0].value_type | lower == "string" %} .to_string() {% endif %};
{% endif %}
{% elif abstract_data_type is object and abstract_data_type is containing("Structure") %}
reader.step_in()?;
Expand All @@ -42,7 +44,11 @@ pub mod {{ target_kind_name | snake }} {
match field_name {
{% for field in fields -%}
{% if field.value_type | is_built_in_type == false %}
"{{ field.name }}" => { abstract_data_type.{{ field.name | snake }} = {{ field.value_type }}::read_from(reader)?; }
{% if field.value_type is containing("Vec") %}
"{{ field.name }}" => { {{ util_macros::read_as_sequence(field=field) }} }
{% else %}
"{{ field.name }}" => { abstract_data_type.{{ field.name | snake }} = {{ field.value_type }}::read_from(reader)?; }
{% endif %}
{% else %}
"{{ field.name }}" => { abstract_data_type.{{ field.name | snake}} = reader.read_{% if field.isl_type_name == "symbol" %}symbol()?.text().unwrap(){% else %}{{ field.value_type | lower | replace(from="string", to ="str") }}()?{% endif %}{% if field.value_type | lower== "string" %} .to_string() {% endif %}; }
{% endif %}
Expand Down Expand Up @@ -99,15 +105,19 @@ pub mod {{ target_kind_name | snake }} {
{% if field.value_type | is_built_in_type == false %}
self.{{ field.name | snake }}.write_to(writer)?;
{% else %}
writer.write_{% if field.isl_type_name == "symbol" %}symbol{% else %}{{ field.value_type | lower }}{% endif %}(self.value)?;
writer.write_{% if field.isl_type_name == "symbol" %}symbol{% else %}{{ field.value_type | lower }}{% endif %}(self.value.to_owned())?;
{% endif %}
{% endfor %}
{% elif abstract_data_type is object and abstract_data_type is containing("Structure") %}
writer.step_in(IonType::Struct)?;
{% for field in fields %}
writer.set_field_name("{{ field.name }}");
{% if field.value_type | is_built_in_type == false %}
self.{{ field.name | snake }}.write_to(writer)?;
{% if field.value_type is containing("Vec") %}
{{ util_macros::write_as_sequence(field=field) }}
{% else %}
self.{{ field.name | snake }}.write_to(writer)?;
{% endif %}
{% else %}
{# TODO: Change the following `to_owned` to only be used when writing i64,f32,f64,bool which require owned value as input #}
writer.write_{% if field.isl_type_name == "symbol" %}symbol{% else %}{{ field.value_type | lower }}{% endif %}(self.{{ field.name | snake }}.to_owned())?;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{# following macro defines statements to read a class field as sequence #}
{% macro read_as_sequence(field) %}
{% if field.abstract_data_type["Sequence"].sequence_type == "List" %}
if reader.ion_type() != Some(IonType::List) {
return validation_error(format!(
"Expected list, found {} while reading {{ field.name | snake }}.", reader.ion_type().unwrap()
));
}
{% elif field.abstract_data_type["Sequence"].sequence_type == "SExp" %}
if reader.ion_type() != Some(IonType::SExp) {
return validation_error(format!(
"Expected sexpression, found {} while reading {{ field.name | snake }}.", reader.ion_type().unwrap()
));
}
{% endif %}
reader.step_in()?;

abstract_data_type.{{ field.name | snake }} = {
let mut values = vec![];

while reader.next()? != StreamItem::Nothing {
{% if field.abstract_data_type["Sequence"].element_type | is_built_in_type == false %}
values.push({{ field.abstract_data_type["Sequence"].element_type }}::read_from(reader)?);
{% else %}
values.push(reader.read_{% if field.isl_type_name == "symbol" %}symbol()?.text().unwrap(){% else %}{{ field.abstract_data_type["Sequence"].element_type | lower | replace(from="string", to ="str") }}()?{% endif %}{% if field.abstract_data_type["Sequence"].element_type | lower== "string" %} .to_string() {% endif %});
{% endif %}
}
values
};
reader.step_out()?;
{% endmacro %}
{# following macro defines statements to write a class field as sequence #}
{% macro write_as_sequence(field) %}
{% if field.abstract_data_type["Sequence"].sequence_type == "List" %}
writer.step_in(IonType::List)?;
{% else %}
writer.step_in(IonType::SExp)?;
{% endif %}
for value in &self.{{ field.name | snake }} {
{% if field.abstract_data_type["Sequence"].element_type | is_built_in_type == false %}
value.write_to(writer)?;
{% else %}
writer.write_{% if field.isl_type_name == "symbol" %}symbol{% else %}{{ field.abstract_data_type["Sequence"].element_type | lower }}{% endif %}(value.to_owned())?;
{% endif %}
}
writer.step_out()?;
{% endmacro %}

0 comments on commit 706e04d

Please sign in to comment.