summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-06-27 22:28:48 +0100
committerMichael Williamson <mike@zwobble.org>2026-06-27 23:25:48 +0100
commit81168752fe9b588f7a8215f86a32f3154c3f593a (patch)
tree7115bc38cd1e1e2f3cb91c6dc5b05bf854189d8e
parent6932fc110e1a6d734675a09fd6f5d889be1250b7 (diff)
Generate Rust types for structs
-rw-r--r--examples/01-struct/hobgoblin.json54
-rw-r--r--examples/01-struct/output/rust/src/point.rs9
-rw-r--r--hobgoblin/src/output/lang/rust/ast.hob50
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java28
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGeneratorConfig.java23
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustNativeTypeConfig.java8
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java117
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java138
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustIdentifier.java28
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustItem.java18
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustModule.java32
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegment.java18
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegmentIdentifier.java32
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructField.java40
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStruct.java36
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustType.java18
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePath.java49
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegment.java32
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriterTests.java16
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java104
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustIdentifierMatcher.java37
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustModuleMatcher.java41
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegmentIdentifierMatcher.java37
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructFieldMatcher.java41
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStructMatcher.java41
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathMatcher.java37
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegmentMatcher.java37
27 files changed, 1055 insertions, 16 deletions
diff --git a/examples/01-struct/hobgoblin.json5 b/examples/01-struct/hobgoblin.json5
index 472e586..b19ddfd 100644
--- a/examples/01-struct/hobgoblin.json5
+++ b/examples/01-struct/hobgoblin.json5
@@ -11,5 +11,9 @@
path: "output/java/src/gen/java",
packageName: "org.zwobble.example.types",
},
+ {
+ generator: "rust-types",
+ path: "output/rust/src",
+ }
],
}
diff --git a/examples/01-struct/output/rust/src/point.rs b/examples/01-struct/output/rust/src/point.rs
new file mode 100644
index 0000000..4a2b09c
--- /dev/null
+++ b/examples/01-struct/output/rust/src/point.rs
@@ -0,0 +1,9 @@
+pub struct Line {
+ start: Point,
+ end: Point,
+}
+
+pub struct Point {
+ x: i32,
+ y: i32,
+}
diff --git a/hobgoblin/src/output/lang/rust/ast.hob b/hobgoblin/src/output/lang/rust/ast.hob
new file mode 100644
index 0000000..f3ff901
--- /dev/null
+++ b/hobgoblin/src/output/lang/rust/ast.hob
@@ -0,0 +1,50 @@
+// == Modules ==
+
+struct RustModule {
+ field name: List[RustIdentifier];
+ field items: List[RustItem];
+}
+
+// == Items ==
+
+sum RustItem {
+ variant RustStructStruct;
+}
+
+struct RustStructStruct {
+ field name: RustIdentifier;
+ field fields: List[RustStructField];
+}
+
+struct RustStructField {
+ field name: RustIdentifier;
+ field type: RustType;
+}
+
+// == Types ==
+
+sum RustType {
+ variant RustTypePath;
+}
+
+struct RustTypePath {
+ field segments: List[RustTypePathSegment];
+}
+
+struct RustTypePathSegment {
+ field pathIdentSegment: RustPathIdentSegment;
+}
+
+sum RustPathIdentSegment {
+ variant RustPathIdentSegmentIdentifier;
+}
+
+struct RustPathIdentSegmentIdentifier {
+ field name: RustIdentifier;
+}
+
+// == Identifiers ==
+
+struct RustIdentifier {
+ field value: String;
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java
index dba5dbf..fe2c3b9 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java
@@ -2,6 +2,7 @@ package org.zwobble.hobgoblin.compiler.output;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.StringWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
@@ -14,6 +15,33 @@ public class CodeWriter implements AutoCloseable {
Writer openWriter() throws IOException;
}
+ public static class InMemoryCodeWriterFile implements CodeWriterFile {
+ private final Optional<String> originalContents;
+ private final StringWriter stringWriter;
+
+ public InMemoryCodeWriterFile(
+ Optional<String> originalContents,
+ StringWriter stringWriter
+ ) {
+ this.originalContents = originalContents;
+ this.stringWriter = stringWriter;
+ }
+
+ @Override
+ public String readString() throws IOException {
+ if (originalContents.isPresent()) {
+ return originalContents.get();
+ } else {
+ throw new NoSuchFileException("");
+ }
+ }
+
+ @Override
+ public Writer openWriter() throws IOException {
+ return stringWriter;
+ }
+ }
+
public record CustomAreas(
Map<String, List<String>> existing,
String customAreaStart,
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGeneratorConfig.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGeneratorConfig.java
new file mode 100644
index 0000000..db0b2fe
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGeneratorConfig.java
@@ -0,0 +1,23 @@
+package org.zwobble.hobgoblin.compiler.output.generators.rust;
+
+import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
+import org.zwobble.hobgoblin.compiler.output.lang.java.ast.*;
+import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath;
+import org.zwobble.hobgoblin.compiler.types.SimpleNativeType;
+
+import java.util.Map;
+import java.util.Optional;
+
+public class RustGeneratorConfig {
+ private static final Map<SimpleNativeType, RustNativeTypeConfig> DEFAULT_NATIVE_TYPE_CONFIGS = Map.ofEntries(
+ Map.entry(NativeTypes.INT_32, new RustNativeTypeConfig(RustTypePath.primitive("i32"))),
+ Map.entry(NativeTypes.INT_64, new RustNativeTypeConfig(RustTypePath.primitive("i64"))),
+ Map.entry(NativeTypes.STRING, new RustNativeTypeConfig(RustTypePath.of("std", "string", "String"))),
+ Map.entry(NativeTypes.LIST_INNER, new RustNativeTypeConfig(RustTypePath.of("std", "vec", "Vec"))),
+ Map.entry(NativeTypes.OPTION_INNER, new RustNativeTypeConfig(RustTypePath.of("std", "option", "Option")))
+ );
+
+ public Optional<RustNativeTypeConfig> nativeTypeConfig(SimpleNativeType type) {
+ return Optional.ofNullable(DEFAULT_NATIVE_TYPE_CONFIGS.get(type));
+ }
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustNativeTypeConfig.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustNativeTypeConfig.java
new file mode 100644
index 0000000..27a6dc8
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustNativeTypeConfig.java
@@ -0,0 +1,8 @@
+package org.zwobble.hobgoblin.compiler.output.generators.rust;
+
+import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType;
+
+public record RustNativeTypeConfig(
+ RustType type
+) {
+}
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 c93be76..b5cf01c 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
@@ -1,14 +1,22 @@
package org.zwobble.hobgoblin.compiler.output.generators.rusttypes;
-import org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceNode;
+import org.zwobble.hobgoblin.compiler.ast.typed.*;
import org.zwobble.hobgoblin.compiler.config.OutputConfig;
import org.zwobble.hobgoblin.compiler.output.generators.Generator;
+import org.zwobble.hobgoblin.compiler.output.generators.rust.RustGeneratorConfig;
+import org.zwobble.hobgoblin.compiler.output.lang.java.JavaWriter;
+import org.zwobble.hobgoblin.compiler.output.lang.rust.RustWriter;
+import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.*;
import org.zwobble.hobgoblin.compiler.typechecker.TypesInfo;
+import org.zwobble.hobgoblin.compiler.types.*;
+import org.zwobble.hobgoblin.compiler.util.Casing;
import org.zwobble.json5.reader.Json5ObjectReader;
+import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
+import java.util.stream.Collectors;
public class RustTypesGenerator implements Generator {
public static final String NAME = "rust-types";
@@ -23,6 +31,7 @@ public class RustTypesGenerator implements Generator {
}
private final Path outputPath;
+ private final RustGeneratorConfig config = new RustGeneratorConfig();
private RustTypesGenerator(Path outputPath) {
this.outputPath = outputPath;
@@ -30,6 +39,112 @@ public class RustTypesGenerator implements Generator {
@Override
public void generate(List<TypedNamespaceNode> namespaces, TypesInfo typesInfo) throws IOException {
+ for (var namespace : namespaces) {
+ var rustModule = generateNamespace(namespace);
+ write(rustModule);
+ }
+ }
+
+ private void write(RustModule rustModule) throws IOException {
+ var path = this.outputPath.resolve(
+ rustModule.name().stream()
+ .map(name -> name.value())
+ .collect(Collectors.joining(File.separator)) + ".rs"
+ );
+ try (var writer = RustWriter.file(path)) {
+ writer.writeModule(rustModule);
+ }
+ }
+
+ private RustModule generateNamespace(TypedNamespaceNode namespace) {
+ var rustModuleName = generateNamespaceName(namespace.namespaceName());
+
+ var rustItems = namespace.body().stream()
+ .flatMap(statement -> generateNamespaceStatement(statement).stream())
+ .toList();
+
+ return new RustModule(rustModuleName, rustItems);
+ }
+
+ private List<RustIdentifier> generateNamespaceName(NamespaceName namespaceName) {
+ return namespaceName.parts().stream()
+ .map(part -> generateModuleName(part))
+ .toList();
+ }
+
+ private List<RustItem> generateNamespaceStatement(TypedNamespaceStatementNode statement) {
+ return switch (statement) {
+ case TypedEnumDefinitionNode enumDefinition -> {
+ yield List.of();
+ }
+
+ case TypedNativeTypeDefinitionNode nativeTypeDefinition -> {
+ yield List.of();
+ }
+
+ case TypedStructDefinitionNode structDefinition -> {
+ var rustStructName = generateTypeName(structDefinition.name());
+
+ var rustFields = structDefinition.fields().stream()
+ .map(field -> new RustStructField(generateFieldName(field.name()), generateRustTypeExpression(field.type())))
+ .toList();
+
+ var rustStruct = new RustStructStruct(rustStructName, rustFields);
+
+ yield List.of(rustStruct);
+ }
+
+ case TypedSumDefinitionNode sumDefinition -> {
+ yield List.of();
+ }
+ };
+ }
+
+ private RustType generateRustTypeExpression(TypedTypeLevelExpressionNode<Type> type) {
+ return switch (type.value()) {
+ case ConstructedNativeType constructedNativeType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case EnumType enumType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case SimpleNativeType simpleNativeType -> {
+ yield this.config.nativeTypeConfig(simpleNativeType)
+ .orElseThrow(() -> new UnsupportedOperationException("TODO"))
+ .type();
+ }
+
+ case StructType structType -> {
+ // TODO: qualify name
+ yield RustTypePath.of(generateTypeName(structType.name()));
+ }
+
+ case SumType sumType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case TypeLevelValueType typeLevelValueType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case TypeParam typeParam -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+ };
+ }
+
+ private RustIdentifier generateFieldName(String fieldName) {
+ return new RustIdentifier(Casing.lowerCamelCaseToSnakeCase(fieldName));
+ }
+
+ private RustIdentifier generateTypeName(String typeName) {
+ return new RustIdentifier(typeName);
+ }
+
+ private RustIdentifier generateModuleName(String part) {
+ return new RustIdentifier(Casing.lowerCamelCaseToSnakeCase(part));
}
}
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
new file mode 100644
index 0000000..16384a4
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java
@@ -0,0 +1,138 @@
+package org.zwobble.hobgoblin.compiler.output.lang.rust;
+
+import org.zwobble.hobgoblin.compiler.output.CodeWriter;
+import org.zwobble.hobgoblin.compiler.output.lang.java.JavaWriter;
+import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.*;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public class RustWriter implements AutoCloseable {
+ private static final String LINE_COMMENT_START = "//";
+
+ public static RustWriter file(CodeWriter.CodeWriterFile file) throws IOException {
+ return new RustWriter(CodeWriter.file(
+ file,
+ LINE_COMMENT_START
+ ));
+ }
+
+ public static RustWriter file(Path path) throws IOException {
+ return new RustWriter(CodeWriter.file(
+ path,
+ LINE_COMMENT_START
+ ));
+ }
+
+ private final CodeWriter writer;
+
+ public RustWriter(CodeWriter writer) {
+ this.writer = writer;
+ }
+
+ @Override
+ public void close() throws IOException {
+ this.writer.close();
+ }
+
+ public void writeModule(RustModule module) throws IOException {
+ writeWithSeparator(
+ module.items(),
+ this::writeItem,
+ () -> {
+ this.writer.newLine();
+ this.writer.newLine();
+ }
+ );
+
+ this.writer.newLine();
+ }
+
+ void writeIdentifier(RustIdentifier identifier) throws IOException {
+ // TODO: handle keywords
+ this.writer.write(identifier.value());
+ }
+
+ void writeItem(RustItem item) throws IOException {
+ switch (item) {
+ case RustStructStruct structStruct -> {
+ writeStructStruct(structStruct);
+ }
+ }
+ }
+
+ private void writeStructStruct(RustStructStruct structStruct) throws IOException {
+ this.writer.write("pub struct ");
+ this.writeIdentifier(structStruct.name());
+ this.writer.write(" {");
+
+ if (!structStruct.fields().isEmpty()) {
+ this.writer.indent();
+
+ for (var field : structStruct.fields()) {
+ this.writer.newLine();
+ this.writeIdentifier(field.name());
+ this.writer.write(": ");
+ this.writeType(field.type());
+ this.writer.write(",");
+ }
+
+ this.writer.dedent();
+ }
+
+ this.writer.newLine();
+ this.writer.write("}");
+ }
+
+ void writeType(RustType type) throws IOException {
+ switch (type) {
+ case RustTypePath typePath -> {
+ this.writeWithSeparator(
+ typePath.segments(),
+ this::writeTypePathSegment,
+ () -> this.writer.write("::")
+ );
+ }
+ }
+ }
+
+ private void writeTypePathSegment(RustTypePathSegment segment) throws IOException {
+ writePathIdentSegment(segment.pathIdentSegment());
+ }
+
+ private void writePathIdentSegment(RustPathIdentSegment pathIdentSegment) throws IOException {
+ switch (pathIdentSegment) {
+ case RustPathIdentSegmentIdentifier pathIdentSegmentIdentifier -> {
+ this.writeIdentifier(pathIdentSegmentIdentifier.name());
+ }
+ }
+ }
+
+ // TODO: de-dupe with Java writer
+ private static <T> void writeWithSeparator(
+ Iterable<T> iterable,
+ WriteElement<T> writeElement,
+ WriteSeparator writeSeparator
+ ) throws IOException {
+ var isFirst = true;
+ for (var element : iterable) {
+ if (!isFirst) {
+ writeSeparator.write();
+ }
+
+ writeElement.write(element);
+
+ if (isFirst) {
+ isFirst = false;
+ }
+ }
+ }
+
+ interface WriteElement<T> {
+ void write(T element) throws IOException;
+ }
+
+ interface WriteSeparator {
+ void write() throws IOException;
+ }
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustIdentifier.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustIdentifier.java
new file mode 100644
index 0000000..34e0ff7
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustIdentifier.java
@@ -0,0 +1,28 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier imports
+
+public record RustIdentifier(String value) {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.Builder("");
+ }
+
+ public record Builder(String value) {
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier(value);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.Builder withValue(String value) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.Builder(value);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustItem.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustItem.java
new file mode 100644
index 0000000..d1fa342
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustItem.java
@@ -0,0 +1,18 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem imports
+
+public sealed interface RustItem permits org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct {
+ public interface Builder {
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem build();
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustModule.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustModule.java
new file mode 100644
index 0000000..e40895e
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustModule.java
@@ -0,0 +1,32 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule imports
+
+public record RustModule(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier> name, java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem> items) {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule.Builder(java.util.List.of(), java.util.List.of());
+ }
+
+ public record Builder(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier> name, java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem> items) {
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule(name, items);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule.Builder withName(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier> name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule.Builder(name, items);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule.Builder withItems(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem> items) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule.Builder(name, items);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegment.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegment.java
new file mode 100644
index 0000000..325a4a4
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegment.java
@@ -0,0 +1,18 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment imports
+
+public sealed interface RustPathIdentSegment permits org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier {
+ public interface Builder {
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment build();
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegmentIdentifier.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegmentIdentifier.java
new file mode 100644
index 0000000..72e6cb0
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegmentIdentifier.java
@@ -0,0 +1,32 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier imports
+
+public record RustPathIdentSegmentIdentifier(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.arbitrary().build());
+ }
+
+ public record Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment.Builder {
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier(name);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.Builder(name);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.Builder name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.Builder(name.build());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructField.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructField.java
new file mode 100644
index 0000000..dc1ddf0
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructField.java
@@ -0,0 +1,40 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField imports
+
+public record RustStructField(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name, org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType type) {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.arbitrary().build(), org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath.arbitrary().build());
+ }
+
+ public record Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name, org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType type) {
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField(name, type);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder(name, type);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.Builder name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder(name.build(), type);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder withType(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType type) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder(name, type);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder withType(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType.Builder type) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder(name, type.build());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField body
+}
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
new file mode 100644
index 0000000..3e9c3ad
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStruct.java
@@ -0,0 +1,36 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct imports
+
+public record RustStructStruct(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name, java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField> fields) 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(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.arbitrary().build(), java.util.List.of());
+ }
+
+ public record Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name, java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField> fields) 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(name, fields);
+ }
+
+ 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(name, fields);
+ }
+
+ 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(name.build(), fields);
+ }
+
+ 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(name, fields);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustType.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustType.java
new file mode 100644
index 0000000..e9d2283
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustType.java
@@ -0,0 +1,18 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType imports
+
+public sealed interface RustType permits org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath {
+ public interface Builder {
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType build();
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType body
+}
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
new file mode 100644
index 0000000..c55b53d
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePath.java
@@ -0,0 +1,49 @@
+// Generated by hobgoblin.
+
+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.Arrays;
+import java.util.List;
+// 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 {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath.Builder(java.util.List.of());
+ }
+
+ public record Builder(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment> segments) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType.Builder {
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath(segments);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath.Builder withSegments(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment> segments) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath.Builder(segments);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath.Builder body
+ }
+
+ // 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)))
+ ));
+ }
+
+ public static RustType of(String... names) {
+ var segments = Arrays.stream(names)
+ .map(name -> new RustTypePathSegment(new RustPathIdentSegmentIdentifier(new RustIdentifier(name))))
+ .toList();
+ return new RustTypePath(segments);
+ }
+
+ public static RustType of(RustIdentifier... names) {
+ var segments = Arrays.stream(names)
+ .map(name -> new RustTypePathSegment(new RustPathIdentSegmentIdentifier(name)))
+ .toList();
+ 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
new file mode 100644
index 0000000..cbd1c69
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegment.java
@@ -0,0 +1,32 @@
+// Generated by hobgoblin.
+
+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) {
+ 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());
+ }
+
+ public record Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment pathIdentSegment) {
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment(pathIdentSegment);
+ }
+
+ 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);
+ }
+
+ 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());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment body
+ // 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/java/JavaWriterTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriterTests.java
index 909300e..992d9bd 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriterTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriterTests.java
@@ -975,21 +975,7 @@ public class JavaWriterTests {
private String write(Write write, Optional<String> originalContents) throws IOException {
var stringWriter = new StringWriter();
var javaWriter = JavaWriter.file(
- new CodeWriter.CodeWriterFile() {
- @Override
- public String readString() throws IOException {
- if (originalContents.isPresent()) {
- return originalContents.get();
- } else {
- throw new NoSuchFileException("");
- }
- }
-
- @Override
- public Writer openWriter() throws IOException {
- return stringWriter;
- }
- }
+ new CodeWriter.InMemoryCodeWriterFile(originalContents, stringWriter)
);
write.write(javaWriter);
return stringWriter.toString();
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
new file mode 100644
index 0000000..bc6f55e
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java
@@ -0,0 +1,104 @@
+package org.zwobble.hobgoblin.compiler.output.lang.rust;
+
+import org.junit.jupiter.api.Test;
+import org.zwobble.hobgoblin.compiler.output.CodeWriter;
+import org.zwobble.hobgoblin.compiler.output.lang.java.JavaWriter;
+import org.zwobble.hobgoblin.compiler.output.lang.java.JavaWriterTests;
+import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.List;
+import java.util.Optional;
+
+import static org.zwobble.precisely.AssertThat.assertThat;
+import static org.zwobble.precisely.Matchers.equalTo;
+
+public class RustWriterTests {
+ @Test
+ public void identifierNonKeywordIsWrittenVerbatim() throws IOException {
+ var rust = new RustIdentifier("rigs");
+
+ var string = write(writer -> writer.writeIdentifier(rust));
+
+ assertThat(string, equalTo("rigs"));
+ }
+
+ @Test
+ public void module() throws IOException {
+ var rust = new RustModule(List.of(new RustIdentifier("shapes")), List.of(
+ new RustStructStruct(new RustIdentifier("Rectangle"), List.of()),
+ new RustStructStruct(new RustIdentifier("Square"), List.of())
+ ));
+
+ var string = write(writer -> writer.writeModule(rust));
+
+ assertThat(string, equalTo("""
+ pub struct Rectangle {
+ }
+
+ pub struct Square {
+ }
+ """));
+ }
+
+ @Test
+ public void emptyStruct() throws IOException {
+ var rust = new RustStructStruct(new RustIdentifier("Rectangle"), List.of());
+
+ var string = write(writer -> writer.writeItem(rust));
+
+ assertThat(string, equalTo("""
+ pub struct Rectangle {
+ }"""));
+ }
+
+ @Test
+ public void emptyStructWithFields() throws IOException {
+ var rust = new RustStructStruct(
+ new RustIdentifier("Rectangle"),
+ List.of(
+ new RustStructField(new RustIdentifier("width"), RustTypePath.primitive("i32")),
+ new RustStructField(new RustIdentifier("height"), RustTypePath.primitive("i32"))
+ )
+ );
+
+ var string = write(writer -> writer.writeItem(rust));
+
+ assertThat(string, equalTo("""
+ pub struct Rectangle {
+ width: i32,
+ height: i32,
+ }"""));
+ }
+
+ @Test
+ public void typeSegmentsAreSeparatedByDoubleColons() throws IOException {
+ var rust = RustTypePath.of("std", "string", "String");
+
+ var string = write(writer -> writer.writeType(rust));
+
+ assertThat(string, equalTo("std::string::String"));
+ }
+
+ private String write(Write write) throws IOException {
+ return write(write, Optional.empty());
+ }
+
+ private String write(Write write, String originalContents) throws IOException {
+ return write(write, Optional.of(originalContents));
+ }
+
+ private String write(Write write, Optional<String> originalContents) throws IOException {
+ var stringWriter = new StringWriter();
+ var rustWriter = RustWriter.file(
+ new CodeWriter.InMemoryCodeWriterFile(originalContents, stringWriter)
+ );
+ write.write(rustWriter);
+ return stringWriter.toString();
+ }
+
+ private interface Write {
+ void write(RustWriter writer) throws IOException;
+ }
+}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustIdentifierMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustIdentifierMatcher.java
new file mode 100644
index 0000000..3edd421
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustIdentifierMatcher.java
@@ -0,0 +1,37 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifierMatcher imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifierMatcher imports
+
+public class RustIdentifierMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifierMatcher isRustIdentifier() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifierMatcher(java.util.List.of());
+ }
+
+ private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier>> submatchers;
+
+ private RustIdentifierMatcher(java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier>> submatchers) {
+ this.submatchers = submatchers;
+ }
+
+ public org.zwobble.precisely.MatchResult match(java.lang.Object actual) {
+ return this.toMatcher().match(actual);
+ }
+
+ public org.zwobble.precisely.TextTree describe() {
+ return this.toMatcher().describe();
+ }
+
+ private org.zwobble.precisely.Matcher<java.lang.Object> toMatcher() {
+ return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.class, this.submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifierMatcher withValue(org.zwobble.precisely.Matcher<? super String> value) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifierMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("value", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier::value, value))).toList());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifierMatcher body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifierMatcher body
+}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustModuleMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustModuleMatcher.java
new file mode 100644
index 0000000..c6a1629
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustModuleMatcher.java
@@ -0,0 +1,41 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModuleMatcher imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModuleMatcher imports
+
+public class RustModuleMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModuleMatcher isRustModule() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModuleMatcher(java.util.List.of());
+ }
+
+ private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule>> submatchers;
+
+ private RustModuleMatcher(java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule>> submatchers) {
+ this.submatchers = submatchers;
+ }
+
+ public org.zwobble.precisely.MatchResult match(java.lang.Object actual) {
+ return this.toMatcher().match(actual);
+ }
+
+ public org.zwobble.precisely.TextTree describe() {
+ return this.toMatcher().describe();
+ }
+
+ private org.zwobble.precisely.Matcher<java.lang.Object> toMatcher() {
+ return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule.class, this.submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModuleMatcher withName(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier>> name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModuleMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule::name, name))).toList());
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModuleMatcher withItems(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem>> items) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModuleMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("items", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule::items, items))).toList());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModuleMatcher body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModuleMatcher body
+}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegmentIdentifierMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegmentIdentifierMatcher.java
new file mode 100644
index 0000000..5f79def
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPathIdentSegmentIdentifierMatcher.java
@@ -0,0 +1,37 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifierMatcher imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifierMatcher imports
+
+public class RustPathIdentSegmentIdentifierMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifierMatcher isRustPathIdentSegmentIdentifier() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifierMatcher(java.util.List.of());
+ }
+
+ private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier>> submatchers;
+
+ private RustPathIdentSegmentIdentifierMatcher(java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier>> submatchers) {
+ this.submatchers = submatchers;
+ }
+
+ public org.zwobble.precisely.MatchResult match(java.lang.Object actual) {
+ return this.toMatcher().match(actual);
+ }
+
+ public org.zwobble.precisely.TextTree describe() {
+ return this.toMatcher().describe();
+ }
+
+ private org.zwobble.precisely.Matcher<java.lang.Object> toMatcher() {
+ return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier.class, this.submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifierMatcher withName(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier> name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifierMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifier::name, name))).toList());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifierMatcher body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegmentIdentifierMatcher body
+}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructFieldMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructFieldMatcher.java
new file mode 100644
index 0000000..a9b0b40
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructFieldMatcher.java
@@ -0,0 +1,41 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructFieldMatcher imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructFieldMatcher imports
+
+public class RustStructFieldMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructFieldMatcher isRustStructField() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructFieldMatcher(java.util.List.of());
+ }
+
+ private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField>> submatchers;
+
+ private RustStructFieldMatcher(java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField>> submatchers) {
+ this.submatchers = submatchers;
+ }
+
+ public org.zwobble.precisely.MatchResult match(java.lang.Object actual) {
+ return this.toMatcher().match(actual);
+ }
+
+ public org.zwobble.precisely.TextTree describe() {
+ return this.toMatcher().describe();
+ }
+
+ private org.zwobble.precisely.Matcher<java.lang.Object> toMatcher() {
+ return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField.class, this.submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructFieldMatcher withName(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier> name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructFieldMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField::name, name))).toList());
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructFieldMatcher withType(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType> type) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructFieldMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("type", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField::type, type))).toList());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructFieldMatcher body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructFieldMatcher body
+}
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
new file mode 100644
index 0000000..e8c6c39
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustStructStructMatcher.java
@@ -0,0 +1,41 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher imports
+
+public class RustStructStructMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher isRustStructStruct() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher(java.util.List.of());
+ }
+
+ private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct>> submatchers;
+
+ private RustStructStructMatcher(java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct>> submatchers) {
+ this.submatchers = submatchers;
+ }
+
+ public org.zwobble.precisely.MatchResult match(java.lang.Object actual) {
+ return this.toMatcher().match(actual);
+ }
+
+ public org.zwobble.precisely.TextTree describe() {
+ return this.toMatcher().describe();
+ }
+
+ private org.zwobble.precisely.Matcher<java.lang.Object> toMatcher() {
+ return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct.class, this.submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher withName(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier> name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct::name, name))).toList());
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher withFields(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructField>> fields) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("fields", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStruct::fields, fields))).toList());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustStructStructMatcher body
+}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathMatcher.java
new file mode 100644
index 0000000..248141a
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathMatcher.java
@@ -0,0 +1,37 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathMatcher imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathMatcher imports
+
+public class RustTypePathMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathMatcher isRustTypePath() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathMatcher(java.util.List.of());
+ }
+
+ private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath>> submatchers;
+
+ private RustTypePathMatcher(java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath>> submatchers) {
+ this.submatchers = submatchers;
+ }
+
+ public org.zwobble.precisely.MatchResult match(java.lang.Object actual) {
+ return this.toMatcher().match(actual);
+ }
+
+ public org.zwobble.precisely.TextTree describe() {
+ return this.toMatcher().describe();
+ }
+
+ private org.zwobble.precisely.Matcher<java.lang.Object> toMatcher() {
+ return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath.class, this.submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathMatcher withSegments(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment>> segments) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("segments", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePath::segments, segments))).toList());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathMatcher body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathMatcher body
+}
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
new file mode 100644
index 0000000..4a73997
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTypePathSegmentMatcher.java
@@ -0,0 +1,37 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.rust.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher imports
+
+public class RustTypePathSegmentMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> {
+ public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher isRustTypePathSegment() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher(java.util.List.of());
+ }
+
+ private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment>> submatchers;
+
+ private RustTypePathSegmentMatcher(java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment>> submatchers) {
+ this.submatchers = submatchers;
+ }
+
+ public org.zwobble.precisely.MatchResult match(java.lang.Object actual) {
+ return this.toMatcher().match(actual);
+ }
+
+ public org.zwobble.precisely.TextTree describe() {
+ return this.toMatcher().describe();
+ }
+
+ private org.zwobble.precisely.Matcher<java.lang.Object> toMatcher() {
+ return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.class, this.submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegmentMatcher withPathIdentSegment(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPathIdentSegment> pathIdentSegment) {
+ 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());
+ }
+
+ // 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
+}