From 1fd5e5b3e6df869c6b48f8ce3b60078311a4a9ea Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 9 Aug 2026 10:27:45 +0100 Subject: Support generic native types in rust-transient-0 --- .../output/generators/rust/RustGenerator.java | 6 ++ .../rusttransient0/RustTransient0Generator.java | 105 ++++++++++++++++----- 2 files changed, 87 insertions(+), 24 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java index ec10107..602c804 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java @@ -119,4 +119,10 @@ public class RustGenerator { public RustIdentifier generateVariantName(SumVariant variant) { return generateTypeName(variant.valueType().name()); } + + public static List functionParamsToClosureParams(List params) { + return params.stream() + .map(param -> new RustIdentifierPattern(param.name())) + .toList(); + } } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java index dfca311..9d959bd 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java @@ -10,6 +10,7 @@ import org.zwobble.hobgoblin.compiler.output.lang.rust.RustTypes; 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.Lists; import org.zwobble.json5.reader.Json5ObjectReader; import java.io.IOException; @@ -527,16 +528,7 @@ public class RustTransient0Generator implements Generator { return new RustFunction( Optional.of(RustVisibility.PUB), encodeMethodName(type), - List.of( - new RustFunctionParam(VALUE_NAME, new RustSharedReferenceType(rustType)), - new RustFunctionParam(WRITER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Write")))), - new RustFunctionParam( - SHARED_VALUES_NAME, - new RustMutableReferenceType( - RustTypes.hashMap(RustTypes.USIZE, RustPath.primitive("i64")) - ) - ) - ), + generateEncodeParams(rustType), Optional.of( RustTypes.ioResult(RustTypes.UNIT) ), @@ -552,6 +544,19 @@ public class RustTransient0Generator implements Generator { ); } + private static List generateEncodeParams(RustPath rustType) { + return List.of( + new RustFunctionParam(VALUE_NAME, new RustSharedReferenceType(rustType)), + new RustFunctionParam(WRITER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Write")))), + new RustFunctionParam( + SHARED_VALUES_NAME, + new RustMutableReferenceType( + RustTypes.hashMap(RustTypes.USIZE, RustPath.primitive("i64")) + ) + ) + ); + } + private RustItem generateDecodeFunction( Type type, RustBlockExpression body @@ -561,12 +566,7 @@ public class RustTransient0Generator implements Generator { return new RustFunction( Optional.of(RustVisibility.PUB), decodeMethodName(type), - List.of( - new RustFunctionParam(READER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Read")))), - new RustFunctionParam(SHARED_VALUES_NAME, new RustMutableReferenceType( - RustTypes.vec(RustTypes.arc(RustTypes.dyn(RustTypes.ANY, RustTypes.SYNC, RustTypes.SEND))) - )) - ), + generateDecodeParams(), Optional.of(RustTypes.ioResult(rustType)), Optional.of(new RustBlockExpression( body.statements(), @@ -575,6 +575,17 @@ public class RustTransient0Generator implements Generator { ); } + private static List generateDecodeParams() { + return List.of( + new RustFunctionParam(READER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Read")))), + new RustFunctionParam( + SHARED_VALUES_NAME, new RustMutableReferenceType( + RustTypes.vec(RustTypes.arc(RustTypes.dyn(RustTypes.ANY, RustTypes.SYNC, RustTypes.SEND))) + ) + ) + ); + } + private RustStatement generateEncode(RustExpression value, Type type) { return switch (type) { case ConstructedNativeType constructedNativeType -> { @@ -587,12 +598,30 @@ public class RustTransient0Generator implements Generator { } else if (constructedNativeType.constructor().equals(NativeTypes.SHARED)) { yield generateEncodeShared(value, constructedNativeType.args().getFirst()); } else { - yield new RustExpressionStatement(generateTodo()); + yield generateEncode( + value, + constructedNativeType.namespaceName(), + type, + constructedNativeType.args().stream() + .map(typeArg -> new RustClosureExpression( + RustGenerator.functionParamsToClosureParams(generateEncodeParams( + this.rustGenerator.generateRustTypeExpression(typeArg) + )), + new RustBlockExpression( + List.of(generateEncode(RustPath.of(VALUE_NAME), typeArg)), + Optional.of(new RustCallExpression( + RustTypes.IO_RESULT_OK, + List.of(new RustTupleExpression(List.of())) + )) + ) + )) + .toList() + ); } } case SimpleType simpleType -> { - yield generateEncode(value, simpleType.namespaceName(), type); + yield generateEncode(value, simpleType.namespaceName(), type, List.of()); } case TypeLevelValueType _ -> { @@ -617,12 +646,25 @@ public class RustTransient0Generator implements Generator { } else if (constructedNativeType.constructor().equals(NativeTypes.SHARED)) { yield generateDecodeShared(constructedNativeType.args().getFirst()); } else { - yield generateTodo(); + yield generateDecode( + constructedNativeType.namespaceName(), + constructedNativeType, + constructedNativeType.args().stream() + .map(typeArg -> new RustClosureExpression( + RustGenerator.functionParamsToClosureParams(generateDecodeParams()), + new RustCallExpression( + RustTypes.IO_RESULT_OK, + List.of(generateDecode(typeArg)) + ) + )) + .toList() + ); } } case SimpleType simpleType -> { - yield generateDecode(simpleType.namespaceName(), type); + NamespaceName typeNamespaceName = simpleType.namespaceName(); + yield generateDecode(typeNamespaceName, type, List.of()); } case TypeLevelValueType _ -> { @@ -635,7 +677,12 @@ public class RustTransient0Generator implements Generator { }; } - private RustStatement generateEncode(RustExpression value, NamespaceName typeNamespaceName, Type type) { + private RustStatement generateEncode( + RustExpression value, + NamespaceName typeNamespaceName, + Type type, + List encodeFunctions + ) { var rustEncodeFunctionPathSegments = new ArrayList<>( this.generateTransient0ModuleName(typeNamespaceName) ); @@ -646,11 +693,18 @@ public class RustTransient0Generator implements Generator { return new RustExpressionStatement(new RustTryPropagationExpression(new RustCallExpression( rustEncodeFunctionPath, - List.of(value, RustPath.of(WRITER_NAME), RustPath.of(SHARED_VALUES_NAME)) + Lists.concat(List.of( + List.of(value, RustPath.of(WRITER_NAME), RustPath.of(SHARED_VALUES_NAME)), + encodeFunctions + )) ))); } - private RustExpression generateDecode(NamespaceName typeNamespaceName, Type type) { + private RustExpression generateDecode( + NamespaceName typeNamespaceName, + Type type, + List decodeFunctions + ) { var rustDecodeFunctionPathSegments = new ArrayList<>( this.generateTransient0ModuleName(typeNamespaceName) ); @@ -661,7 +715,10 @@ public class RustTransient0Generator implements Generator { return new RustTryPropagationExpression(new RustCallExpression( rustDecodeFunctionPath, - List.of(RustPath.of(READER_NAME), RustPath.of(SHARED_VALUES_NAME)) + Lists.concat(List.of( + List.of(RustPath.of(READER_NAME), RustPath.of(SHARED_VALUES_NAME)), + decodeFunctions + )) )); } -- cgit v1.2.3