diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-08-14 11:01:46 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-08-14 11:01:46 +0100 |
| commit | 00cfa7a56b31f0b629a54a77e1934d25471f8156 (patch) | |
| tree | b0074167b96b6c131cae54de7bab51858dae66e7 | |
| parent | 8811a6c2b0a80297d239cbcda169dca8c809458a (diff) | |
Add type params to struct in Rust AST
6 files changed, 66 insertions, 19 deletions
diff --git a/hobgoblin/src/output/lang/rust/ast.hob b/hobgoblin/src/output/lang/rust/ast.hob index 3847dbd..7f7c8ff 100644 --- a/hobgoblin/src/output/lang/rust/ast.hob +++ b/hobgoblin/src/output/lang/rust/ast.hob @@ -47,6 +47,7 @@ struct RustTypeAlias { struct RustStructStruct { field attributes: List[RustOuterAttribute]; field name: RustIdentifier; + field typeParams: List[RustTypeParam]; field fields: Option[List[RustStructField]]; field docComment: DocComment; } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java index 4744322..2070ec3 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java @@ -139,6 +139,7 @@ public class RustTypesGenerator implements Generator { var rustStruct = new RustStructStruct( rustAttributes, rustStructName, + List.of(), rustFields, structDefinition.docComment() ); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java index 3438147..da534b2 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java @@ -143,15 +143,7 @@ public class RustWriter implements AutoCloseable { this.writer.write("type "); this.writeIdentifier(typeAlias.name()); - if (!typeAlias.params().isEmpty()) { - this.writer.write("<"); - writeWithSeparator( - typeAlias.params(), - this::writeTypeParam, - () -> this.writer.write(", ") - ); - this.writer.write(">"); - } + this.writeTypeParams(typeAlias.params()); this.writer.write(" = "); this.writeType(typeAlias.type()); this.writer.write(";"); @@ -164,6 +156,7 @@ public class RustWriter implements AutoCloseable { this.writerOuterAttributes(structStruct.attributes()); this.writer.write("pub struct "); this.writeIdentifier(structStruct.name()); + this.writeTypeParams(structStruct.typeParams()); if (structStruct.fields().isEmpty()) { this.writer.write(";"); @@ -286,6 +279,18 @@ public class RustWriter implements AutoCloseable { // === Generic parameters === + private void writeTypeParams(List<RustTypeParam> typeParams) throws IOException { + if (!typeParams.isEmpty()) { + this.writer.write("<"); + writeWithSeparator( + typeParams, + this::writeTypeParam, + () -> this.writer.write(", ") + ); + this.writer.write(">"); + } + } + private void writeTypeParam(RustTypeParam typeParam) throws IOException { this.writeIdentifier(typeParam.name()); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStruct.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStruct.java index 2838a68..d07a6c8 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStruct.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStruct.java @@ -8,57 +8,75 @@ package org.zwobble.hobgoblin.compiler.output.lang.rust.ast; public record RustStructStruct( java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustOuterAttribute> attributes, org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name, + java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam> typeParams, java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField>> fields, org.zwobble.hobgoblin.compiler.ast.DocComment docComment ) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem { public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder arbitrary() { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(java.util.List.of(), org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.arbitrary().build(), java.util.Optional.empty(), org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment()); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(java.util.List.of(), org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.arbitrary().build(), java.util.List.of(), java.util.Optional.empty(), org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment()); } public record Builder( java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustOuterAttribute> attributes, org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name, + java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam> typeParams, java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField>> fields, org.zwobble.hobgoblin.compiler.ast.DocComment docComment ) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem.Builder { public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct build() { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct(attributes, name, fields, docComment); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct(attributes, name, typeParams, fields, docComment); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder withAttributes(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustOuterAttribute> attributes) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, fields, docComment); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, typeParams, fields, docComment); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder addAttribute(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustOuterAttribute attribute) { var attributes = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustOuterAttribute>(this.attributes); attributes.add(attribute); - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, fields, docComment); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, typeParams, fields, docComment); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder addAttribute(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustOuterAttribute.Builder attribute) { var attributes = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustOuterAttribute>(this.attributes); attributes.add(attribute.build()); - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, fields, docComment); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, typeParams, fields, docComment); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, fields, docComment); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, typeParams, fields, docComment); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.Builder name) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name.build(), fields, docComment); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name.build(), typeParams, fields, docComment); + } + + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder withTypeParams(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam> typeParams) { + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, typeParams, fields, docComment); + } + + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder addTypeParam(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam typeParam) { + var typeParams = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam>(this.typeParams); + typeParams.add(typeParam); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, typeParams, fields, docComment); + } + + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder addTypeParam(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam.Builder typeParam) { + var typeParams = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam>(this.typeParams); + typeParams.add(typeParam.build()); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, typeParams, fields, docComment); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder withFields(java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField>> fields) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, fields, docComment); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, typeParams, fields, docComment); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder withFields(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField> fields) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, java.util.Optional.of(fields), docComment); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, typeParams, java.util.Optional.of(fields), docComment); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder withDocComment(org.zwobble.hobgoblin.compiler.ast.DocComment docComment) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, fields, docComment); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder(attributes, name, typeParams, fields, docComment); } // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder body diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java index b8179f2..feabc12 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java @@ -213,6 +213,22 @@ public class RustWriterTests { } @Test + public void structWithTypeParams() throws IOException { + var rust = RustStructStruct.arbitrary() + .withName(RustIdentifier.of("X")) + .addTypeParam(RustTypeParam.arbitrary().withName(RustIdentifier.of("T1"))) + .addTypeParam(RustTypeParam.arbitrary().withName(RustIdentifier.of("T2"))) + .withFields(List.of()) + .build(); + + var string = write(writer -> writer.writeItem(rust)); + + assertThat(string, equalTo(""" + pub struct X<T1, T2> { + }""")); + } + + @Test public void structWithFields() throws IOException { var rust = RustStructStruct.arbitrary() .withName(new RustIdentifier("Rectangle")) diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStructMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStructMatcher.java index b4c984d..b10f3c6 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStructMatcher.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStructMatcher.java @@ -42,6 +42,12 @@ public final class RustStructStructMatcher implements org.zwobble.precisely.Matc return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher(submatchers); } + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher withTypeParams(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam>> typeParams) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("typeParams", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct::typeParams, typeParams)); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher(submatchers); + } + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher withFields(org.zwobble.precisely.Matcher<? super java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField>>> fields) { var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct>>(this.submatchers); submatchers.add(org.zwobble.precisely.Matchers.has("fields", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct::fields, fields)); |
