From 904d7f9db65fa5542cdd44b8dd360c271a931cc6 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 31 Jul 2026 15:06:36 +0100 Subject: Handle boxed variants in rust-transient-0 --- .../java/org/zwobble/example/Transient0Tests.java | 17 +++++++++++++++++ .../13-transient-0/output/rust/src/gen/data.rs | 18 ++++++++++++++++++ .../output/rust/src/gen/data/transient_0.rs | 22 ++++++++++++++++++++++ examples/13-transient-0/output/rust/src/lib.rs | 19 ++++++++++++++++++- examples/13-transient-0/src/data.hob | 5 +++++ .../rusttransient0/RustTransient0Generator.java | 10 +++++++++- .../compiler/output/lang/rust/RustTypes.java | 5 +++-- 7 files changed, 92 insertions(+), 4 deletions(-) diff --git a/examples/13-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java b/examples/13-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java index c439235..8161920 100644 --- a/examples/13-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java +++ b/examples/13-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java @@ -224,6 +224,23 @@ public class Transient0Tests { ); } + @Test + public void sumWithBoxedVariants() throws IOException { + assertRoundTripEncoding( + "SumWithBoxedVariants_VariantOne", + new VariantOne(10), + HobgoblinTransient0Data::encodeSumWithBoxedVariants, + HobgoblinTransient0Data::decodeSumWithBoxedVariants + ); + + assertRoundTripEncoding( + "SumWithBoxedVariants_VariantTwo", + new VariantTwo(25), + HobgoblinTransient0Data::encodeSumWithBoxedVariants, + HobgoblinTransient0Data::decodeSumWithBoxedVariants + ); + } + @Test public void structWithSum() throws IOException { var value = new StructWithSum( diff --git a/examples/13-transient-0/output/rust/src/gen/data.rs b/examples/13-transient-0/output/rust/src/gen/data.rs index 50a0673..77bcbe8 100644 --- a/examples/13-transient-0/output/rust/src/gen/data.rs +++ b/examples/13-transient-0/output/rust/src/gen/data.rs @@ -92,6 +92,24 @@ pub struct VariantTwo { pub a: ::core::primitive::i64, } +#[derive(Clone, Debug, Hash, PartialEq)] +pub enum SumWithBoxedVariants { + VariantOne(::std::boxed::Box::), + VariantTwo(::std::boxed::Box::), +} + +impl ::std::convert::From:: for crate::data::SumWithBoxedVariants { + fn from(value: crate::data::VariantOne) -> Self { + Self::VariantOne(::std::boxed::Box::new(value)) + } +} + +impl ::std::convert::From:: for crate::data::SumWithBoxedVariants { + fn from(value: crate::data::VariantTwo) -> Self { + Self::VariantTwo(::std::boxed::Box::new(value)) + } +} + #[derive(Clone, Debug, Hash, PartialEq)] pub struct StructWithSum { pub inner: crate::data::SumWithVariants, diff --git a/examples/13-transient-0/output/rust/src/gen/data/transient_0.rs b/examples/13-transient-0/output/rust/src/gen/data/transient_0.rs index 8bf68cb..f2bf149 100644 --- a/examples/13-transient-0/output/rust/src/gen/data/transient_0.rs +++ b/examples/13-transient-0/output/rust/src/gen/data/transient_0.rs @@ -230,6 +230,28 @@ pub fn decode_variant_two(reader: &mut impl std::io::Read, shared_values: &mut : ::std::io::Result::Ok(crate::data::VariantTwo { a: a }) } +pub fn encode_sum_with_boxed_variants(value: &crate::data::SumWithBoxedVariants, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { + match value { + crate::data::SumWithBoxedVariants::VariantOne(value) => { + crate::transient_0::encode_int_32(&0, writer, shared_values)?; + crate::data::transient_0::encode_variant_one(value, writer, shared_values)?; + }, + crate::data::SumWithBoxedVariants::VariantTwo(value) => { + crate::transient_0::encode_int_32(&1, writer, shared_values)?; + crate::data::transient_0::encode_variant_two(value, writer, shared_values)?; + }, + }; + ::std::io::Result::Ok(()) +} + +pub fn decode_sum_with_boxed_variants(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::>) -> ::std::io::Result:: { + ::std::io::Result::Ok(match &crate::transient_0::decode_int_32(reader, shared_values)? { + 0 => crate::data::SumWithBoxedVariants::VariantOne(::std::boxed::Box::new(crate::data::transient_0::decode_variant_one(reader, shared_values)?)), + 1 => crate::data::SumWithBoxedVariants::VariantTwo(::std::boxed::Box::new(crate::data::transient_0::decode_variant_two(reader, shared_values)?)), + _ => todo!(), + }) +} + pub fn encode_struct_with_sum(value: &crate::data::StructWithSum, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { crate::data::transient_0::encode_sum_with_variants(&value.inner, writer, shared_values)?; crate::transient_0::encode_int_32(&value.b, writer, shared_values)?; diff --git a/examples/13-transient-0/output/rust/src/lib.rs b/examples/13-transient-0/output/rust/src/lib.rs index b858f24..df50cae 100644 --- a/examples/13-transient-0/output/rust/src/lib.rs +++ b/examples/13-transient-0/output/rust/src/lib.rs @@ -8,7 +8,7 @@ mod test { use std::path::PathBuf; use std::sync::Arc; use std::collections::HashMap; - use super::data::{EnumWithVariants, StructSingleton, StructWithBool, StructWithDifferentSharedTypes, StructWithEnum, StructWithInt8, StructWithInt32, StructWithInt64, StructWithList, StructWithListOfShared, StructWithOption, StructWithSharedSumAndVariant, StructWithString, StructWithStruct, StructWithSum, SumWithVariants, VariantOne, VariantTwo }; + use super::data::{EnumWithVariants, StructSingleton, StructWithBool, StructWithDifferentSharedTypes, StructWithEnum, StructWithInt8, StructWithInt32, StructWithInt64, StructWithList, StructWithListOfShared, StructWithOption, StructWithSharedSumAndVariant, StructWithString, StructWithStruct, StructWithSum, SumWithBoxedVariants, SumWithVariants, VariantOne, VariantTwo }; #[test] fn struct_singleton() { @@ -196,6 +196,23 @@ mod test { ); } + #[test] + fn sum_with_boxed_variants() { + assert_round_trip_encoding( + "SumWithBoxedVariants_VariantOne", + SumWithBoxedVariants::VariantOne(Box::new(VariantOne { a: 10 })), + super::data::transient_0::encode_sum_with_boxed_variants, + super::data::transient_0::decode_sum_with_boxed_variants, + ); + + assert_round_trip_encoding( + "SumWithBoxedVariants_VariantTwo", + SumWithBoxedVariants::VariantTwo(Box::new(VariantTwo { a: 25 })), + super::data::transient_0::encode_sum_with_boxed_variants, + super::data::transient_0::decode_sum_with_boxed_variants, + ); + } + #[test] fn struct_with_sum() { let value = StructWithSum { diff --git a/examples/13-transient-0/src/data.hob b/examples/13-transient-0/src/data.hob index 39a55c9..0744b79 100644 --- a/examples/13-transient-0/src/data.hob +++ b/examples/13-transient-0/src/data.hob @@ -66,6 +66,11 @@ struct VariantTwo { field a: Int64; } +sum SumWithBoxedVariants { + variant VariantOne box; + variant VariantTwo box; +} + struct StructWithSum { field inner: SumWithVariants; field b: Int32; 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 2af97a8..ea1949d 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 @@ -483,9 +483,17 @@ public class RustTransient0Generator implements Generator { var variantPath = this.rustGenerator.generateRustTypeExpression(sumDefinition.type()) .addSegment(RustPathSegment.of(this.rustGenerator.generateVariantName(variantType))); + var valueExpression = generateDecode(variantType); + if (variant.isBox()) { + valueExpression = new RustCallExpression( + RustTypes.BOX.addSegment(RustPathSegment.of("new")), + List.of(valueExpression) + ); + } + return new RustMatchArm( new RustLiteralPattern(new RustIntegerLiteral(variantIndex, Optional.empty())), - new RustCallExpression(variantPath, List.of(generateDecode(variantType))) + new RustCallExpression(variantPath, List.of(valueExpression)) ); }) .collect(toArrayList()); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java index ec473b1..5e6303a 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java @@ -22,9 +22,10 @@ public class RustTypes { public static RustPath ANY = RustPath.global("std", "any", "Any"); + public static final RustPath BOX = RustPath.global("std", "boxed", "Box"); + public static RustPath box(RustType elementType) { - return RustPath.global("std", "boxed", "Box") - .withArgs(List.of(elementType)); + return BOX.withArgs(List.of(elementType)); } public static RustPath hashMap(RustType keyType, RustType valueType) { -- cgit v1.2.3