diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-07-03 15:07:18 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-07-03 15:07:18 +0100 |
| commit | 7311b7638de76ba68f197f891248b426e656e730 (patch) | |
| tree | 2dee49ed55134676fbcd8a41ae3598c0ed5261c2 /src/main/java/org | |
| parent | 139dc93bb10daea87eba99e8f28d8a668c94e13b (diff) | |
Add constructor functions for Rust enum variants
Diffstat (limited to 'src/main/java/org')
4 files changed, 98 insertions, 2 deletions
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 2e8b244..a7d39eb 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 @@ -171,7 +171,60 @@ public class RustTypesGenerator implements Generator { var rustEnum = new RustEnum(rustEnumName, rustVariants, sumDefinition.docComment()); - return List.of(rustEnum); + var rustCreateVariantFunctions = sumDefinition.variants().stream() + .<RustAssociatedItem>map(variant -> { + var variantType = generateRustTypeExpression(variant.type(), context); + +// if (variant.isBox()) { +// variantType = RustTypePath.global("std", "boxed", "Box") +// .withArgs(List.of(variantType)); +// } +// + var variantName = generateVariantName(variant.type().value()); +// +// return new RustEnumVariant( +// variantName, +// new RustEnumVariantTuple(List.of( +// new RustTupleField(variantType) +// )) +// ); + + var innerValueName = new RustIdentifier("value"); + RustExpression innerValue = new RustPathInExpression(List.of( + new RustPathExprSegment( + new RustPathIdentSegmentIdentifier(innerValueName), + Optional.empty() + ) + )); + + if (variant.isBox()) { + innerValue = new RustCallExpression( + RustPathInExpression.global("std", "boxed", "Box", "new"), + List.of(innerValue) + ); + } + + return new RustFunction( + new RustIdentifier(Casing.upperCamelCaseToSnakeCase(variantName.value())), + List.of( + new RustFunctionParam(innerValueName, variantType) + ), + Optional.of(RustTypePath.selfType()), + Optional.of(new RustBlockExpression( + List.of(), + Optional.of( + new RustCallExpression( + RustPathInExpression.selfType(variantName), + List.of(innerValue) + ) + ) + )) + ); + }) + .toList(); + var rustImpl = new RustInherentImpl(RustTypePath.of(rustEnumName), rustCreateVariantFunctions); + + return List.of(rustEnum, rustImpl); } private RustType generateRustTypeExpression( 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 6db480e..b732390 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 @@ -113,7 +113,7 @@ public class RustWriter implements AutoCloseable { } private void writeFunction(RustFunction function) throws IOException { - this.writer.write("fn "); + this.writer.write("pub fn "); this.writeIdentifier(function.name()); this.writer.write("("); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathExprSegment.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathExprSegment.java index 9e55ecf..7246ac0 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathExprSegment.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathExprSegment.java @@ -38,6 +38,14 @@ public record RustPathExprSegment(org.zwobble.hobgoblin.compiler.output.lang.rus } // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathExprSegment body + public static RustPathExprSegment global() { + return new RustPathExprSegment(new RustPathIdentSegmentGlobal(), Optional.empty()); + } + + public static RustPathExprSegment selfType() { + return new RustPathExprSegment(new RustPathIdentSegmentSelfType(), Optional.empty()); + } + public RustPathExprSegment withArgs(List<RustType> args) { if (this.args.isPresent()) { throw new IllegalArgumentException("Expression path segment already has args"); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathInExpression.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathInExpression.java index be28b7c..78baabc 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathInExpression.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathInExpression.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.stream.Stream; // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathInExpression imports public record RustPathInExpression(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathExprSegment> segments) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustExpression { @@ -50,6 +51,40 @@ public record RustPathInExpression(java.util.List<org.zwobble.hobgoblin.compiler return new RustPathInExpression(segments); } + public static RustExpression global(String... names) { + return qualified(RustPathExprSegment.global(), names); + } + + public static RustPathInExpression selfType(RustIdentifier... names) { + return qualified(RustPathExprSegment.selfType(), names); + } + + private static RustPathInExpression qualified(RustPathExprSegment qualifier, RustIdentifier... names) { + var segments = Stream.concat( + Stream.of(qualifier), + Arrays.stream(names) + .map(name -> new RustPathExprSegment( + new RustPathIdentSegmentIdentifier(name), + Optional.empty() + )) + ) + .toList(); + return new RustPathInExpression(segments); + } + + private static RustPathInExpression qualified(RustPathExprSegment qualifier, String... names) { + var segments = Stream.concat( + Stream.of(qualifier), + Arrays.stream(names) + .map(name -> new RustPathExprSegment( + new RustPathIdentSegmentIdentifier(new RustIdentifier(name)), + Optional.empty() + )) + ) + .toList(); + return new RustPathInExpression(segments); + } + public RustPathInExpression withArgs(List<RustType> args) { var segments = new ArrayList<>(this.segments); var lastSegment = segments.removeLast().withArgs(args); |
