summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-06-30 20:56:33 +0100
committerMichael Williamson <mike@zwobble.org>2026-06-30 20:56:33 +0100
commit6752ace624c60ca0ee4a251d1001766acad9b4cb (patch)
treeca0dd0cc3186fcf55fd95c4ed940ca954f0a655a /src
parentf55983f8a5fefe039df83fc601679fc32e04581e (diff)
Support Rust type paths with generic args
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java10
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePath.java26
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegment.java26
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java10
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegmentMatcher.java4
5 files changed, 66 insertions, 10 deletions
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 9153d83..6cd67c6 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
@@ -110,6 +110,16 @@ public class RustWriter implements AutoCloseable {
private void writeTypePathSegment(RustTypePathSegment segment) throws IOException {
writePathIdentSegment(segment.pathIdentSegment());
+
+ if (segment.args().isPresent()) {
+ this.writer.write("<");
+ writeWithSeparator(
+ segment.args().get(),
+ this::writeType,
+ () -> this.writer.write(", ")
+ );
+ this.writer.write(">");
+ }
}
private void writePathIdentSegment(RustPathIdentSegment pathIdentSegment) throws IOException {
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePath.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePath.java
index c55b53d..9b44334 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePath.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePath.java
@@ -3,8 +3,10 @@
package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath imports
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Optional;
// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath imports
public record RustTypePath(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment> segments) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType {
@@ -28,22 +30,38 @@ public record RustTypePath(java.util.List<org.zwobble.hobgoblin.compiler.output.
// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath body
public static RustTypePath primitive(String name) {
return new RustTypePath(List.of(
- new RustTypePathSegment(new RustPathIdentSegmentIdentifier(new RustIdentifier(name)))
+ new RustTypePathSegment(
+ new RustPathIdentSegmentIdentifier(new RustIdentifier(name)),
+ Optional.empty()
+ )
));
}
- public static RustType of(String... names) {
+ public static RustTypePath of(String... names) {
var segments = Arrays.stream(names)
- .map(name -> new RustTypePathSegment(new RustPathIdentSegmentIdentifier(new RustIdentifier(name))))
+ .map(name -> new RustTypePathSegment(
+ new RustPathIdentSegmentIdentifier(new RustIdentifier(name)),
+ Optional.empty()
+ ))
.toList();
return new RustTypePath(segments);
}
public static RustType of(RustIdentifier... names) {
var segments = Arrays.stream(names)
- .map(name -> new RustTypePathSegment(new RustPathIdentSegmentIdentifier(name)))
+ .map(name -> new RustTypePathSegment(
+ new RustPathIdentSegmentIdentifier(name),
+ Optional.empty()
+ ))
.toList();
return new RustTypePath(segments);
}
+
+ public RustType withArgs(List<RustType> args) {
+ var segments = new ArrayList<>(this.segments);
+ var lastSegment = segments.removeLast().withArgs(args);
+ segments.add(lastSegment);
+ return new RustTypePath(segments);
+ }
// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath body
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegment.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegment.java
index cbd1c69..4473aa3 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegment.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegment.java
@@ -5,22 +5,29 @@ package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment imports
// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment imports
-public record RustTypePathSegment(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment pathIdentSegment) {
+import java.util.List;
+import java.util.Optional;
+
+public record RustTypePathSegment(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment pathIdentSegment, java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType>> args) {
public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder arbitrary() {
- return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.arbitrary().build());
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.arbitrary().build(), java.util.Optional.empty());
}
- public record Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment pathIdentSegment) {
+ public record Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment pathIdentSegment, java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType>> args) {
public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment build() {
- return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment(pathIdentSegment);
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment(pathIdentSegment, args);
}
public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder withPathIdentSegment(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment pathIdentSegment) {
- return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(pathIdentSegment);
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(pathIdentSegment, args);
}
public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder withPathIdentSegment(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment.Builder pathIdentSegment) {
- return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(pathIdentSegment.build());
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(pathIdentSegment.build(), args);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder withArgs(java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType>> args) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(pathIdentSegment, args);
}
// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder body
@@ -28,5 +35,12 @@ public record RustTypePathSegment(org.zwobble.hobgoblin.compiler.output.lang.rus
}
// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment body
+ public RustTypePathSegment withArgs(List<RustType> args) {
+ if (this.args.isPresent()) {
+ throw new IllegalArgumentException("Type path segment already has args");
+ }
+
+ return new RustTypePathSegment(this.pathIdentSegment, Optional.of(args));
+ }
// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment 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 eca8685..f52d275 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
@@ -95,6 +95,16 @@ public class RustWriterTests {
assertThat(string, equalTo("std::string::String"));
}
+ @Test
+ public void typeSegmentGenericArgsAreWritten() throws IOException {
+ var rust = RustTypePath.of("std", "collections", "HashMap")
+ .withArgs(List.of(RustTypePath.of("i32"), RustTypePath.of("f64")));
+
+ var string = write(writer -> writer.writeType(rust));
+
+ assertThat(string, equalTo("std::collections::HashMap<i32, f64>"));
+ }
+
private String write(Write write) throws IOException {
return write(write, Optional.empty());
}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegmentMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegmentMatcher.java
index 4a73997..ebefac9 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegmentMatcher.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegmentMatcher.java
@@ -32,6 +32,10 @@ public class RustTypePathSegmentMatcher implements org.zwobble.precisely.Matcher
return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("pathIdentSegment", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment::pathIdentSegment, pathIdentSegment))).toList());
}
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher withArgs(org.zwobble.precisely.Matcher<? super java.util.Optional<java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType>>> args) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("args", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment::args, args))).toList());
+ }
+
// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher body
// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher body
}