Skip to content

Commit

Permalink
Allow mutable records (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
skeet70 authored Jun 3, 2024
1 parent 06138a4 commit a89a49b
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 9 deletions.
18 changes: 12 additions & 6 deletions src/gen_java/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ trait CodeType: Debug {
pub struct Config {
pub(super) package_name: Option<String>,
pub(super) cdylib_name: Option<String>,
generate_immutable_records: Option<bool>,
#[serde(default)]
custom_types: HashMap<String, CustomTypeConfig>,
#[serde(default)]
Expand Down Expand Up @@ -108,6 +109,11 @@ impl Config {
"uniffi".into()
}
}

/// Whether to generate immutable records (`record` instead of `class`)
pub fn generate_immutable_records(&self) -> bool {
self.generate_immutable_records.unwrap_or(false)
}
}

#[derive(Debug, Default, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -265,9 +271,9 @@ impl JavaCodeOracle {
nm.to_string().to_lower_camel_case()
}

/// Get the idiomatic getter name for a variable.
pub fn getter_name(&self, nm: &str) -> String {
format!("get{}", nm.to_string().to_upper_camel_case())
/// Get the idiomatic setter name for a variable.
pub fn setter(&self, nm: &str) -> String {
format!("set{}", nm.to_string().to_upper_camel_case())
}

/// Get the idiomatic Java rendering of an individual enum variant.
Expand Down Expand Up @@ -612,9 +618,9 @@ mod filters {
Ok(JavaCodeOracle.var_name(nm))
}

/// Get the idiomatic Java getter method name.
pub fn getter_name(nm: &str) -> Result<String, askama::Error> {
Ok(JavaCodeOracle.getter_name(nm))
/// Get the idiomatic Java setter method name.
pub fn setter(nm: &str) -> Result<String, askama::Error> {
Ok(JavaCodeOracle.setter(nm))
}

/// Get a String representing the name used for an individual enum variant.
Expand Down
2 changes: 1 addition & 1 deletion src/templates/ErrorTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public static class {{ variant_name }} extends {{ type_name }}{% if contains_obj
}

{% for field in variant.fields() -%}
public {{ field|type_name(ci) }} {{ field.name()|getter_name}}() {
public {{ field|type_name(ci) }} {{ field.name()|var_name}}() {
return this.{{ field.name()|var_name }};
}
{% endfor %}
Expand Down
57 changes: 55 additions & 2 deletions src/templates/RecordTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import java.util.List;
import java.util.Map;
import java.nio.ByteBuffer;
import java.util.Objects;

{%- if rec.has_fields() %}
{%- call java::docstring(rec, 0) %}
{%- if rec.has_fields() %}
{%- if config.generate_immutable_records() %}
public record {{ type_name }}(
{%- for field in rec.fields() %}
{%- call java::docstring(field, 4) %}
Expand All @@ -21,8 +23,59 @@ public void destroy() {
}
{% endif %}
}
{% else %}
public class {{ type_name }} {
{%- for field in rec.fields() %}
{%- call java::docstring(field, 4) %}
private {{ field|type_name(ci) }} {{ field.name()|var_name -}};
{%- endfor %}

public {{ type_name }}(
{%- for field in rec.fields() %}
{{ field|type_name(ci) }} {{ field.name()|var_name -}}
{% if !loop.last %}, {% endif %}
{%- endfor %}
) {
{%- for field in rec.fields() %}
{% let field_var_name = field.name()|var_name %}
this.{{ field_var_name }} = {{ field_var_name -}};
{%- endfor %}
}

{%- for field in rec.fields() %}
{% let field_var_name = field.name()|var_name %}
public {{ field|type_name(ci) }} {{ field_var_name }}() {
return this.{{ field_var_name }};
}
{%- endfor %}

{%- for field in rec.fields() %}
{%- let field_var_name = field.name()|var_name %}
public void {{ field.name()|setter}}({{ field|type_name(ci) }} {{ field_var_name }}) {
this.{{ field_var_name }} = {{ field_var_name }};
}
{%- endfor %}

@Override
public boolean equals(Object other) {
if (other instanceof {{ type_name }}) {
{{ type_name }} t = ({{ type_name }}) other;
return ({% for field in rec.fields() %}{% let field_var_name = field.name()|var_name %}
{#- currently all primitive are already referenced by their boxed values in generated code, so `.equals` works for everything #}
({{ field_var_name }}.equals(t.{{ field_var_name }})){% if !loop.last%} && {% endif %}
{% endfor %}
);
};
return false;
}

@Override
public int hashCode() {
return Objects.hash({% for field in rec.fields() %}{{ field.name()|var_name }}{% if !loop.last%}, {% endif %}{% endfor %});
}
}
{% endif %}
{%- else -%}
{%- call java::docstring(rec, 0) %}
public class {{ type_name }} {
@Override
public boolean equals(Object other) {
Expand Down

0 comments on commit a89a49b

Please sign in to comment.