From 264d74517334d2dfea1d2d893394f67b0a6ed0ad Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 2 Jul 2026 11:45:21 +0100 Subject: Support custom configs for native types in Rust types output --- .../05-native-type-custom-config/hobgoblin.json5 | 12 ++++++ .../output/rust/.gitignore | 1 + .../output/rust/Cargo.lock | 7 ++++ .../output/rust/Cargo.toml | 6 +++ .../output/rust/rust-toolchain.toml | 2 + .../output/rust/src/main.rs | 9 +++++ .../output/rust/src/point.rs | 7 ++++ .../hobgoblin/compiler/config/ProjectConfig.java | 2 +- .../generators/rust/RustGeneratorConfig.java | 47 ++++++++++++++++++++-- .../generators/rusttypes/RustTypesGenerator.java | 16 ++++++-- 10 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 examples/05-native-type-custom-config/output/rust/.gitignore create mode 100644 examples/05-native-type-custom-config/output/rust/Cargo.lock create mode 100644 examples/05-native-type-custom-config/output/rust/Cargo.toml create mode 100644 examples/05-native-type-custom-config/output/rust/rust-toolchain.toml create mode 100644 examples/05-native-type-custom-config/output/rust/src/main.rs create mode 100644 examples/05-native-type-custom-config/output/rust/src/point.rs diff --git a/examples/05-native-type-custom-config/hobgoblin.json5 b/examples/05-native-type-custom-config/hobgoblin.json5 index 1c92a49..f925903 100644 --- a/examples/05-native-type-custom-config/hobgoblin.json5 +++ b/examples/05-native-type-custom-config/hobgoblin.json5 @@ -10,12 +10,24 @@ }, ], }, + rust: { + nativeTypes: [ + { + hobgoblin: "point.Point", + rust: "crate::Point", + }, + ], + }, }, generators: [ { generator: "java-types", path: "output/java/src/gen/java", }, + { + generator: "rust-types", + path: "output/rust/src", + }, ], }, } diff --git a/examples/05-native-type-custom-config/output/rust/.gitignore b/examples/05-native-type-custom-config/output/rust/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/examples/05-native-type-custom-config/output/rust/.gitignore @@ -0,0 +1 @@ +/target diff --git a/examples/05-native-type-custom-config/output/rust/Cargo.lock b/examples/05-native-type-custom-config/output/rust/Cargo.lock new file mode 100644 index 0000000..9dc6e3e --- /dev/null +++ b/examples/05-native-type-custom-config/output/rust/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "example" +version = "0.1.0" diff --git a/examples/05-native-type-custom-config/output/rust/Cargo.toml b/examples/05-native-type-custom-config/output/rust/Cargo.toml new file mode 100644 index 0000000..5d4c622 --- /dev/null +++ b/examples/05-native-type-custom-config/output/rust/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "example" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/examples/05-native-type-custom-config/output/rust/rust-toolchain.toml b/examples/05-native-type-custom-config/output/rust/rust-toolchain.toml new file mode 100644 index 0000000..4fedb95 --- /dev/null +++ b/examples/05-native-type-custom-config/output/rust/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.96" diff --git a/examples/05-native-type-custom-config/output/rust/src/main.rs b/examples/05-native-type-custom-config/output/rust/src/main.rs new file mode 100644 index 0000000..af7be7f --- /dev/null +++ b/examples/05-native-type-custom-config/output/rust/src/main.rs @@ -0,0 +1,9 @@ +mod point; + +use point::Line; + +struct Point(i32, i32); + +fn main() { + let line = Line { start: Point(10, 25), end: Point(25, 10) }; +} diff --git a/examples/05-native-type-custom-config/output/rust/src/point.rs b/examples/05-native-type-custom-config/output/rust/src/point.rs new file mode 100644 index 0000000..b073f86 --- /dev/null +++ b/examples/05-native-type-custom-config/output/rust/src/point.rs @@ -0,0 +1,7 @@ +// Generated by hobgoblin. + +/// A straight line from one point to another. +pub struct Line { + pub start: crate::Point, + pub end: crate::Point, +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/config/ProjectConfig.java b/src/main/java/org/zwobble/hobgoblin/compiler/config/ProjectConfig.java index 835b496..2899756 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/config/ProjectConfig.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/config/ProjectConfig.java @@ -46,7 +46,7 @@ public record ProjectConfig( JavaPreciselyMatchersGenerator.parseGeneratorConfig(projectRoot, generatorJson, langsJson); case RustTypesGenerator.NAME -> - RustTypesGenerator.parseGeneratorConfig(projectRoot, generatorJson); + RustTypesGenerator.parseGeneratorConfig(projectRoot, generatorJson, langsJson); default -> throw new UnknownGeneratorError( 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 index db0b2fe..5d777ea 100644 --- 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 @@ -1,14 +1,55 @@ 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.parser.Parser; import org.zwobble.hobgoblin.compiler.types.SimpleNativeType; +import org.zwobble.json5.reader.Json5ObjectReader; +import java.util.HashMap; import java.util.Map; import java.util.Optional; -public class RustGeneratorConfig { +public record RustGeneratorConfig( + Map nativeTypeConfigs +) { + public static RustGeneratorConfig parseLangsConfig(Optional langsJson) { + var output = langsJson.flatMap(json -> json.getObject("rust")); + + if (output.isEmpty()) { + return new RustGeneratorConfig(DEFAULT_NATIVE_TYPE_CONFIGS); + } + + var nativeTypeConfigs = parseNativeTypeConfigs(output.get()); + + return new RustGeneratorConfig( + nativeTypeConfigs + ); + } + + private static Map parseNativeTypeConfigs(Json5ObjectReader output) { + // TODO: remove duplication with Java config + var nativeTypeConfigs = new HashMap(DEFAULT_NATIVE_TYPE_CONFIGS); + output.getArrayOfObjects("nativeTypes").ifPresent(nativeTypesJson -> { + for (var nativeTypeJson : nativeTypesJson) { + var hobgoblinTypeString = nativeTypeJson.getString("hobgoblin").valueAsSourceText(); + var hobgoblinTypeName = Parser.parseQualifiedTypeName(hobgoblinTypeString); + var hobgoblinType = new SimpleNativeType( + hobgoblinTypeName.namespaceName(), + hobgoblinTypeName.name() + ); + + // TODO: less hacky type representation + var rustTypeString = nativeTypeJson.getString("rust").value(); + var rustType = RustTypePath.of(rustTypeString); + + nativeTypeConfigs.put(hobgoblinType, new RustNativeTypeConfig(rustType)); + } + }); + + return nativeTypeConfigs; + } + private static final Map 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"))), @@ -18,6 +59,6 @@ public class RustGeneratorConfig { ); public Optional nativeTypeConfig(SimpleNativeType type) { - return Optional.ofNullable(DEFAULT_NATIVE_TYPE_CONFIGS.get(type)); + return Optional.ofNullable(this.nativeTypeConfigs.get(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 4593d38..9092e16 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 @@ -16,25 +16,33 @@ import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; public class RustTypesGenerator implements Generator { public static final String NAME = "rust-types"; - public static OutputConfig parseGeneratorConfig(Path projectRoot, Json5ObjectReader output) { + public static OutputConfig parseGeneratorConfig( + Path projectRoot, + Json5ObjectReader output, + Optional langsJson + ) { return () -> { var relativeOutputPath = output.getString("path").value(); var outputPath = projectRoot.resolve(relativeOutputPath); - return new RustTypesGenerator(outputPath); + var rustConfig = RustGeneratorConfig.parseLangsConfig(langsJson); + + return new RustTypesGenerator(outputPath, rustConfig); }; } private final Path outputPath; - private final RustGeneratorConfig config = new RustGeneratorConfig(); + private final RustGeneratorConfig config; - private RustTypesGenerator(Path outputPath) { + private RustTypesGenerator(Path outputPath, RustGeneratorConfig config) { this.outputPath = outputPath; + this.config = config; } @Override -- cgit v1.2.3