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 --- .../java/org/zwobble/example/Transient0Tests.java | 23 ++++++++ examples/15-transient-0/output/rust/src/data.rs | 36 ++++++++++++- .../output/rust/src/gen/data/transient_0.rs | 62 ++++++++++++++++++++-- examples/15-transient-0/output/rust/src/lib.rs | 23 +++++++- 4 files changed, 138 insertions(+), 6 deletions(-) (limited to 'examples/15-transient-0/output') diff --git a/examples/15-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java b/examples/15-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java index 528d43c..ba43aed 100644 --- a/examples/15-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java +++ b/examples/15-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java @@ -15,12 +15,14 @@ import java.util.Optional; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.zwobble.example.types.data.EnumWithVariants; +import org.zwobble.example.types.data.GenericNative; import org.zwobble.example.types.data.Native; import org.zwobble.example.types.data.StructSingleton; import org.zwobble.example.types.data.StructWithBool; import org.zwobble.example.types.data.StructWithBox; import org.zwobble.example.types.data.StructWithDifferentSharedTypes; import org.zwobble.example.types.data.StructWithEnum; +import org.zwobble.example.types.data.StructWithGenericNative; import org.zwobble.example.types.data.StructWithInt8; import org.zwobble.example.types.data.StructWithInt32; import org.zwobble.example.types.data.StructWithInt64; @@ -273,6 +275,27 @@ public class Transient0Tests { ); } + @Test + public void structWithGenericNative() throws IOException { + var value = new StructWithGenericNative( + new GenericNative(10, "x1"), + new GenericNative( + Optional.of("x2"), + new GenericNative( + Optional.of("x3"), + new GenericNative("x4", "x5") + ) + ) + ); + + assertRoundTripEncoding( + "StructWithGenericNative", + value, + HobgoblinTransient0Data::encodeStructWithGenericNative, + HobgoblinTransient0Data::decodeStructWithGenericNative + ); + } + @Test public void structWithBox() throws IOException { var value = new StructWithBox( diff --git a/examples/15-transient-0/output/rust/src/data.rs b/examples/15-transient-0/output/rust/src/data.rs index 2cf748b..cc0eb13 100644 --- a/examples/15-transient-0/output/rust/src/data.rs +++ b/examples/15-transient-0/output/rust/src/data.rs @@ -17,7 +17,7 @@ pub mod transient_0 { use ::std::any::Any; use ::std::sync::Arc; use ::std::vec::Vec; - use super::Native; + use super::{GenericNative, Native}; include!("./gen/data/transient_0.rs"); @@ -39,4 +39,38 @@ pub mod transient_0 { let b = crate::transient_0::decode_int_32(reader, shared_values)?; Ok(Native { a, b }) } + + type Encode = fn( + &T, + &mut TWrite, + &mut ::std::collections::HashMap::, + ) -> std::io::Result<()>; + + type Decode = fn( + &mut TRead, + &mut Vec>, + ) -> std::io::Result; + + pub fn encode_generic_native( + value: &GenericNative, + writer: &mut TWrite, + shared_values: &mut ::std::collections::HashMap::, + encode_a: Encode, + encode_b: Encode, + ) -> std::io::Result<()> { + encode_a(&value.a, writer, shared_values)?; + encode_b(&value.b, writer, shared_values)?; + Ok(()) + } + + pub fn decode_generic_native( + reader: &mut TRead, + shared_values: &mut Vec>, + decode_a: Decode, + decode_b: Decode, + ) -> std::io::Result> { + let a = decode_a(reader, shared_values)?; + let b = decode_b(reader, shared_values)?; + Ok(GenericNative { a, b }) + } } diff --git a/examples/15-transient-0/output/rust/src/gen/data/transient_0.rs b/examples/15-transient-0/output/rust/src/gen/data/transient_0.rs index 383a564..b72964c 100644 --- a/examples/15-transient-0/output/rust/src/gen/data/transient_0.rs +++ b/examples/15-transient-0/output/rust/src/gen/data/transient_0.rs @@ -275,14 +275,68 @@ pub fn decode_struct_with_native(reader: &mut impl std::io::Read, shared_values: } pub fn encode_struct_with_generic_native(value: &crate::data::StructWithGenericNative, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { - todo!(); - todo!(); + crate::data::transient_0::encode_generic_native(&value.a, writer, shared_values, |value, writer, shared_values| { + crate::transient_0::encode_int_32(value, writer, shared_values)?; + ::std::io::Result::Ok(()) + }, |value, writer, shared_values| { + crate::transient_0::encode_string(value, writer, shared_values)?; + ::std::io::Result::Ok(()) + })?; + crate::data::transient_0::encode_generic_native(&value.b, writer, shared_values, |value, writer, shared_values| { + match value { + ::std::option::Option::Some(value) => { + crate::transient_0::encode_bool(&true, writer, shared_values)?; + crate::transient_0::encode_string(&value, writer, shared_values)?; + }, + ::std::option::Option::None => { + crate::transient_0::encode_bool(&false, writer, shared_values)?; + }, + }; + ::std::io::Result::Ok(()) + }, |value, writer, shared_values| { + crate::data::transient_0::encode_generic_native(value, writer, shared_values, |value, writer, shared_values| { + match value { + ::std::option::Option::Some(value) => { + crate::transient_0::encode_bool(&true, writer, shared_values)?; + crate::transient_0::encode_string(&value, writer, shared_values)?; + }, + ::std::option::Option::None => { + crate::transient_0::encode_bool(&false, writer, shared_values)?; + }, + }; + ::std::io::Result::Ok(()) + }, |value, writer, shared_values| { + crate::data::transient_0::encode_generic_native(value, writer, shared_values, |value, writer, shared_values| { + crate::transient_0::encode_string(value, writer, shared_values)?; + ::std::io::Result::Ok(()) + }, |value, writer, shared_values| { + crate::transient_0::encode_string(value, writer, shared_values)?; + ::std::io::Result::Ok(()) + })?; + ::std::io::Result::Ok(()) + })?; + ::std::io::Result::Ok(()) + })?; ::std::io::Result::Ok(()) } pub fn decode_struct_with_generic_native(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::>) -> ::std::io::Result:: { - let a = todo!(); - let b = todo!(); + let a = crate::data::transient_0::decode_generic_native(reader, shared_values, |reader, shared_values| ::std::io::Result::Ok(crate::transient_0::decode_int_32(reader, shared_values)?), |reader, shared_values| ::std::io::Result::Ok(crate::transient_0::decode_string(reader, shared_values)?))?; + let b = crate::data::transient_0::decode_generic_native(reader, shared_values, |reader, shared_values| ::std::io::Result::Ok({ + let is_some = crate::transient_0::decode_bool(reader, shared_values)?; + if is_some { + ::std::option::Option::Some(crate::transient_0::decode_string(reader, shared_values)?) + } else { + ::std::option::Option::None + } + }), |reader, shared_values| ::std::io::Result::Ok(crate::data::transient_0::decode_generic_native(reader, shared_values, |reader, shared_values| ::std::io::Result::Ok({ + let is_some = crate::transient_0::decode_bool(reader, shared_values)?; + if is_some { + ::std::option::Option::Some(crate::transient_0::decode_string(reader, shared_values)?) + } else { + ::std::option::Option::None + } + }), |reader, shared_values| ::std::io::Result::Ok(crate::data::transient_0::decode_generic_native(reader, shared_values, |reader, shared_values| ::std::io::Result::Ok(crate::transient_0::decode_string(reader, shared_values)?), |reader, shared_values| ::std::io::Result::Ok(crate::transient_0::decode_string(reader, shared_values)?))?))?))?; ::std::io::Result::Ok(crate::data::StructWithGenericNative { a: a, b: b }) } diff --git a/examples/15-transient-0/output/rust/src/lib.rs b/examples/15-transient-0/output/rust/src/lib.rs index 22ecdb4..a51afff 100644 --- a/examples/15-transient-0/output/rust/src/lib.rs +++ b/examples/15-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, Native, StructSingleton, StructWithBool, StructWithBox, StructWithDifferentSharedTypes, StructWithEnum, StructWithInt8, StructWithInt32, StructWithInt64, StructWithList, StructWithListOfShared, StructWithNative, StructWithOption, StructWithSharedSumAndVariant, StructWithString, StructWithStruct, StructWithSum, SumWithBoxedVariants, SumWithVariants, VariantOne, VariantTwo }; + use super::data::{EnumWithVariants, GenericNative, Native, StructSingleton, StructWithBool, StructWithBox, StructWithDifferentSharedTypes, StructWithEnum, StructWithGenericNative, StructWithInt8, StructWithInt32, StructWithInt64, StructWithList, StructWithListOfShared, StructWithNative, StructWithOption, StructWithSharedSumAndVariant, StructWithString, StructWithStruct, StructWithSum, SumWithBoxedVariants, SumWithVariants, VariantOne, VariantTwo }; #[test] fn struct_singleton() { @@ -242,6 +242,27 @@ mod test { ); } + #[test] + fn struct_with_generic_native() { + let value = StructWithGenericNative { + a: GenericNative { a: 10, b: "x1".to_string() }, + b: GenericNative { + a: Some("x2".to_string()), + b: GenericNative { + a: Some("x3".to_string()), + b: GenericNative { a: "x4".to_string(), b: "x5".to_string() }, + }, + }, + }; + + assert_round_trip_encoding( + "StructWithGenericNative", + value, + super::data::transient_0::encode_struct_with_generic_native, + super::data::transient_0::decode_struct_with_generic_native, + ); + } + #[test] fn struct_with_box() { let value = StructWithBox { -- cgit v1.2.3