diff options
16 files changed, 541 insertions, 147 deletions
diff --git a/examples/16-transient-0/output/java/src/main/java/org/zwobble/example/types/data/transient0/HobgoblinTransient0Data.java b/examples/16-transient-0/output/java/src/main/java/org/zwobble/example/types/data/transient0/HobgoblinTransient0Data.java index 1eea54c..9993ed2 100644 --- a/examples/16-transient-0/output/java/src/main/java/org/zwobble/example/types/data/transient0/HobgoblinTransient0Data.java +++ b/examples/16-transient-0/output/java/src/main/java/org/zwobble/example/types/data/transient0/HobgoblinTransient0Data.java @@ -90,6 +90,28 @@ public final class HobgoblinTransient0Data { return new org.zwobble.example.types.data.StructWithStruct(inner, c); } + public static <A, B> void encodeGenericStruct(org.zwobble.example.types.data.GenericStruct<A, B> value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues, org.zwobble.example.types.transient0.Encoder<A> encoder$A, org.zwobble.example.types.transient0.Encoder<B> encoder$B) throws java.io.IOException { + encoder$A.encode(value.a(), outputStream, sharedValues); + encoder$B.encode(value.b(), outputStream, sharedValues); + } + + public static <A, B> org.zwobble.example.types.data.GenericStruct<A, B> decodeGenericStruct(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues, org.zwobble.example.types.transient0.Decoder<A> decoder$A, org.zwobble.example.types.transient0.Decoder<B> decoder$B) throws java.io.IOException { + var a = decoder$A.decode(inputStream, sharedValues); + var b = decoder$B.decode(inputStream, sharedValues); + return new org.zwobble.example.types.data.GenericStruct<A, B>(a, b); + } + + public static void encodeStructWithGenericStruct(org.zwobble.example.types.data.StructWithGenericStruct value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { + org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericStruct(value.a(), outputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeInt32, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeString); + org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericStruct(value.b(), outputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$1); + } + + public static org.zwobble.example.types.data.StructWithGenericStruct decodeStructWithGenericStruct(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { + var a = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericStruct(inputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeInt32, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeString); + var b = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericStruct(inputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$1); + return new org.zwobble.example.types.data.StructWithGenericStruct(a, b); + } + public static void encodeStructWithList(org.zwobble.example.types.data.StructWithList value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { org.zwobble.example.types.transient0.HobgoblinTransient0Builtins.encodeInt64((long) value.a().size(), outputStream, sharedValues); for (var element : value.a()) { @@ -276,12 +298,12 @@ public final class HobgoblinTransient0Data { public static void encodeStructWithGenericNative(org.zwobble.example.types.data.StructWithGenericNative value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericNative(value.a(), outputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeInt32, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeString); - org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericNative(value.b(), outputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$1); + org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericNative(value.b(), outputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$2); } public static org.zwobble.example.types.data.StructWithGenericNative decodeStructWithGenericNative(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { var a = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericNative(inputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeInt32, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeString); - var b = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericNative(inputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$1); + var b = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericNative(inputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$2); return new org.zwobble.example.types.data.StructWithGenericNative(a, b); } @@ -519,20 +541,38 @@ public final class HobgoblinTransient0Data { return value; } - private static void encode$constructedType$1(org.zwobble.example.types.data.GenericNative<java.util.Optional<String>, org.zwobble.example.types.data.GenericNative<String, String>> value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { - org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericNative(value, outputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$2); + private static void encode$constructedType$1(org.zwobble.example.types.data.GenericStruct<java.util.Optional<String>, org.zwobble.example.types.data.GenericStruct<String, String>> value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { + org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericStruct(value, outputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$3); + } + + private static org.zwobble.example.types.data.GenericStruct<java.util.Optional<String>, org.zwobble.example.types.data.GenericStruct<String, String>> decode$constructedType$1(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { + var value = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericStruct(inputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$3); + return value; + } + + private static void encode$constructedType$2(org.zwobble.example.types.data.GenericNative<java.util.Optional<String>, org.zwobble.example.types.data.GenericNative<String, String>> value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { + org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericNative(value, outputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::encode$constructedType$4); + } + + private static org.zwobble.example.types.data.GenericNative<java.util.Optional<String>, org.zwobble.example.types.data.GenericNative<String, String>> decode$constructedType$2(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { + var value = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericNative(inputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$4); + return value; + } + + private static void encode$constructedType$3(org.zwobble.example.types.data.GenericStruct<String, String> value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { + org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericStruct(value, outputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeString, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeString); } - private static org.zwobble.example.types.data.GenericNative<java.util.Optional<String>, org.zwobble.example.types.data.GenericNative<String, String>> decode$constructedType$1(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { - var value = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericNative(inputStream, sharedValues, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$0, org.zwobble.example.types.data.transient0.HobgoblinTransient0Data::decode$constructedType$2); + private static org.zwobble.example.types.data.GenericStruct<String, String> decode$constructedType$3(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { + var value = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericStruct(inputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeString, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeString); return value; } - private static void encode$constructedType$2(org.zwobble.example.types.data.GenericNative<String, String> value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { + private static void encode$constructedType$4(org.zwobble.example.types.data.GenericNative<String, String> value, java.io.OutputStream outputStream, java.util.Map<org.zwobble.example.types.transient0.HobgoblinTransient0TaggedSharedValue, java.lang.Long> sharedValues) throws java.io.IOException { org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.encodeGenericNative(value, outputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeString, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::encodeString); } - private static org.zwobble.example.types.data.GenericNative<String, String> decode$constructedType$2(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { + private static org.zwobble.example.types.data.GenericNative<String, String> decode$constructedType$4(java.io.InputStream inputStream, java.util.List<java.lang.Object> sharedValues) throws java.io.IOException { var value = org.zwobble.example.types.data.transient0.HobgoblinTransient0Data.decodeGenericNative(inputStream, sharedValues, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeString, org.zwobble.example.types.transient0.HobgoblinTransient0Builtins::decodeString); return value; } diff --git a/examples/16-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java b/examples/16-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java index ba43aed..b5c3611 100644 --- a/examples/16-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java +++ b/examples/16-transient-0/output/java/src/test/java/org/zwobble/example/Transient0Tests.java @@ -16,6 +16,7 @@ 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.GenericStruct; import org.zwobble.example.types.data.Native; import org.zwobble.example.types.data.StructSingleton; import org.zwobble.example.types.data.StructWithBool; @@ -23,6 +24,7 @@ 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.StructWithGenericStruct; import org.zwobble.example.types.data.StructWithInt8; import org.zwobble.example.types.data.StructWithInt32; import org.zwobble.example.types.data.StructWithInt64; @@ -125,6 +127,27 @@ public class Transient0Tests { } @Test + public void structWithGenericStruct() throws IOException { + var value = new StructWithGenericStruct( + new GenericStruct(10, "x1"), + new GenericStruct( + Optional.of("x2"), + new GenericStruct( + Optional.of("x3"), + new GenericStruct("x4", "x5") + ) + ) + ); + + assertRoundTripEncoding( + "StructWithGenericStruct", + value, + HobgoblinTransient0Data::encodeStructWithGenericStruct, + HobgoblinTransient0Data::decodeStructWithGenericStruct + ); + } + + @Test public void structWithList() throws IOException { var value = new StructWithList( List.of(10L, 25L), diff --git a/examples/16-transient-0/output/rust/src/gen/data.rs b/examples/16-transient-0/output/rust/src/gen/data.rs index 6f1d5b5..fe67736 100644 --- a/examples/16-transient-0/output/rust/src/gen/data.rs +++ b/examples/16-transient-0/output/rust/src/gen/data.rs @@ -40,6 +40,18 @@ pub struct StructWithStruct { } #[derive(Clone, Debug, Hash, PartialEq)] +pub struct GenericStruct<A, B> { + pub a: A, + pub b: B, +} + +#[derive(Clone, Debug, Hash, PartialEq)] +pub struct StructWithGenericStruct { + pub a: crate::data::GenericStruct::<::core::primitive::i32, ::std::string::String>, + pub b: crate::data::GenericStruct::<::std::option::Option::<::std::string::String>, crate::data::GenericStruct::<::std::option::Option::<::std::string::String>, crate::data::GenericStruct::<::std::string::String, ::std::string::String>>>, +} + +#[derive(Clone, Debug, Hash, PartialEq)] pub struct StructWithList { pub a: ::std::vec::Vec::<::core::primitive::i64>, pub b: ::std::vec::Vec::<crate::data::StructWithInt32>, diff --git a/examples/16-transient-0/output/rust/src/gen/data/transient_0.rs b/examples/16-transient-0/output/rust/src/gen/data/transient_0.rs index b72964c..67a6a11 100644 --- a/examples/16-transient-0/output/rust/src/gen/data/transient_0.rs +++ b/examples/16-transient-0/output/rust/src/gen/data/transient_0.rs @@ -1,86 +1,164 @@ // Generated by hobgoblin. -pub fn encode_struct_singleton(value: &crate::data::StructSingleton, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_singleton(value: &crate::data::StructSingleton, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { ::std::io::Result::Ok(()) } -pub fn decode_struct_singleton(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructSingleton> { +pub fn decode_struct_singleton(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructSingleton> { ::std::io::Result::Ok(crate::data::StructSingleton) } -pub fn encode_struct_with_bool(value: &crate::data::StructWithBool, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_bool(value: &crate::data::StructWithBool, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { crate::transient_0::encode_bool(&value.a, writer, shared_values)?; crate::transient_0::encode_bool(&value.b, writer, shared_values)?; ::std::io::Result::Ok(()) } -pub fn decode_struct_with_bool(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithBool> { +pub fn decode_struct_with_bool(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithBool> { let a = crate::transient_0::decode_bool(reader, shared_values)?; let b = crate::transient_0::decode_bool(reader, shared_values)?; ::std::io::Result::Ok(crate::data::StructWithBool { a: a, b: b }) } -pub fn encode_struct_with_int_8(value: &crate::data::StructWithInt8, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_int_8(value: &crate::data::StructWithInt8, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { crate::transient_0::encode_int_8(&value.a, writer, shared_values)?; crate::transient_0::encode_int_8(&value.b, writer, shared_values)?; ::std::io::Result::Ok(()) } -pub fn decode_struct_with_int_8(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithInt8> { +pub fn decode_struct_with_int_8(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithInt8> { let a = crate::transient_0::decode_int_8(reader, shared_values)?; let b = crate::transient_0::decode_int_8(reader, shared_values)?; ::std::io::Result::Ok(crate::data::StructWithInt8 { a: a, b: b }) } -pub fn encode_struct_with_int_32(value: &crate::data::StructWithInt32, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_int_32(value: &crate::data::StructWithInt32, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { crate::transient_0::encode_int_32(&value.a, writer, shared_values)?; crate::transient_0::encode_int_32(&value.b, writer, shared_values)?; ::std::io::Result::Ok(()) } -pub fn decode_struct_with_int_32(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithInt32> { +pub fn decode_struct_with_int_32(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithInt32> { let a = crate::transient_0::decode_int_32(reader, shared_values)?; let b = crate::transient_0::decode_int_32(reader, shared_values)?; ::std::io::Result::Ok(crate::data::StructWithInt32 { a: a, b: b }) } -pub fn encode_struct_with_int_64(value: &crate::data::StructWithInt64, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_int_64(value: &crate::data::StructWithInt64, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { crate::transient_0::encode_int_64(&value.a, writer, shared_values)?; crate::transient_0::encode_int_64(&value.b, writer, shared_values)?; ::std::io::Result::Ok(()) } -pub fn decode_struct_with_int_64(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithInt64> { +pub fn decode_struct_with_int_64(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithInt64> { let a = crate::transient_0::decode_int_64(reader, shared_values)?; let b = crate::transient_0::decode_int_64(reader, shared_values)?; ::std::io::Result::Ok(crate::data::StructWithInt64 { a: a, b: b }) } -pub fn encode_struct_with_string(value: &crate::data::StructWithString, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_string(value: &crate::data::StructWithString, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { crate::transient_0::encode_string(&value.a, writer, shared_values)?; crate::transient_0::encode_string(&value.b, writer, shared_values)?; ::std::io::Result::Ok(()) } -pub fn decode_struct_with_string(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithString> { +pub fn decode_struct_with_string(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithString> { let a = crate::transient_0::decode_string(reader, shared_values)?; let b = crate::transient_0::decode_string(reader, shared_values)?; ::std::io::Result::Ok(crate::data::StructWithString { a: a, b: b }) } -pub fn encode_struct_with_struct(value: &crate::data::StructWithStruct, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_struct(value: &crate::data::StructWithStruct, 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_struct_with_int_32(&value.inner, writer, shared_values)?; crate::transient_0::encode_int_32(&value.c, writer, shared_values)?; ::std::io::Result::Ok(()) } -pub fn decode_struct_with_struct(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithStruct> { +pub fn decode_struct_with_struct(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithStruct> { let inner = crate::data::transient_0::decode_struct_with_int_32(reader, shared_values)?; let c = crate::transient_0::decode_int_32(reader, shared_values)?; ::std::io::Result::Ok(crate::data::StructWithStruct { inner: inner, c: c }) } -pub fn encode_struct_with_list(value: &crate::data::StructWithList, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_generic_struct<TWrite: ::std::io::Write, A, B>(value: &crate::data::GenericStruct::<A, B>, writer: &mut TWrite, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>, encode_a: crate::transient_0::Encode::<A, TWrite>, encode_b: crate::transient_0::Encode::<B, TWrite>) -> ::std::io::Result::<()> { + encode_a(&value.a, writer, shared_values)?; + encode_b(&value.b, writer, shared_values)?; + ::std::io::Result::Ok(()) +} + +pub fn decode_generic_struct<TRead: ::std::io::Read, A, B>(reader: &mut TRead, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>, decode_a: crate::transient_0::Decode::<TRead, A>, decode_b: crate::transient_0::Decode::<TRead, B>) -> ::std::io::Result::<crate::data::GenericStruct::<A, B>> { + let a = decode_a(reader, shared_values)?; + let b = decode_b(reader, shared_values)?; + ::std::io::Result::Ok(crate::data::GenericStruct::<A, B> { a: a, b: b }) +} + +pub fn encode_struct_with_generic_struct(value: &crate::data::StructWithGenericStruct, 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_generic_struct(&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_struct(&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_struct(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_struct(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_struct(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithGenericStruct> { + let a = crate::data::transient_0::decode_generic_struct(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_struct(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_struct(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_struct(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::StructWithGenericStruct { a: a, b: b }) +} + +pub fn encode_struct_with_list(value: &crate::data::StructWithList, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { { crate::transient_0::encode_int_64(&(((&value.a).len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?, writer, shared_values)?; for element in &value.a { @@ -96,7 +174,7 @@ pub fn encode_struct_with_list(value: &crate::data::StructWithList, writer: &mut ::std::io::Result::Ok(()) } -pub fn decode_struct_with_list(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithList> { +pub fn decode_struct_with_list(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithList> { let a = { let len = crate::transient_0::decode_int_64(reader, shared_values)?; let mut elements = ::std::vec::Vec::with_capacity((len.try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?); @@ -116,7 +194,7 @@ pub fn decode_struct_with_list(reader: &mut impl std::io::Read, shared_values: & ::std::io::Result::Ok(crate::data::StructWithList { a: a, b: b }) } -pub fn encode_struct_with_option(value: &crate::data::StructWithOption, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_option(value: &crate::data::StructWithOption, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { match &value.a { ::std::option::Option::Some(value) => { crate::transient_0::encode_bool(&true, writer, shared_values)?; @@ -138,7 +216,7 @@ pub fn encode_struct_with_option(value: &crate::data::StructWithOption, writer: ::std::io::Result::Ok(()) } -pub fn decode_struct_with_option(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithOption> { +pub fn decode_struct_with_option(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithOption> { let a = { let is_some = crate::transient_0::decode_bool(reader, shared_values)?; if is_some { @@ -158,7 +236,7 @@ pub fn decode_struct_with_option(reader: &mut impl std::io::Read, shared_values: ::std::io::Result::Ok(crate::data::StructWithOption { a: a, b: b }) } -pub fn encode_enum_with_variants(value: &crate::data::EnumWithVariants, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_enum_with_variants(value: &crate::data::EnumWithVariants, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { crate::transient_0::encode_int_32(&match value { crate::data::EnumWithVariants::Zero => 0, crate::data::EnumWithVariants::One => 1, @@ -167,7 +245,7 @@ pub fn encode_enum_with_variants(value: &crate::data::EnumWithVariants, writer: ::std::io::Result::Ok(()) } -pub fn decode_enum_with_variants(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::EnumWithVariants> { +pub fn decode_enum_with_variants(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::EnumWithVariants> { ::std::io::Result::Ok(match &crate::transient_0::decode_int_32(reader, shared_values)? { 0 => crate::data::EnumWithVariants::Zero, 1 => crate::data::EnumWithVariants::One, @@ -176,19 +254,19 @@ pub fn decode_enum_with_variants(reader: &mut impl std::io::Read, shared_values: }) } -pub fn encode_struct_with_enum(value: &crate::data::StructWithEnum, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_enum(value: &crate::data::StructWithEnum, 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_enum_with_variants(&value.inner, writer, shared_values)?; crate::transient_0::encode_int_32(&value.c, writer, shared_values)?; ::std::io::Result::Ok(()) } -pub fn decode_struct_with_enum(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithEnum> { +pub fn decode_struct_with_enum(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithEnum> { let inner = crate::data::transient_0::decode_enum_with_variants(reader, shared_values)?; let c = crate::transient_0::decode_int_32(reader, shared_values)?; ::std::io::Result::Ok(crate::data::StructWithEnum { inner: inner, c: c }) } -pub fn encode_sum_with_variants(value: &crate::data::SumWithVariants, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_sum_with_variants(value: &crate::data::SumWithVariants, 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::SumWithVariants::VariantOne(value) => { crate::transient_0::encode_int_32(&0, writer, shared_values)?; @@ -202,7 +280,7 @@ pub fn encode_sum_with_variants(value: &crate::data::SumWithVariants, writer: &m ::std::io::Result::Ok(()) } -pub fn decode_sum_with_variants(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::SumWithVariants> { +pub fn decode_sum_with_variants(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::SumWithVariants> { ::std::io::Result::Ok(match &crate::transient_0::decode_int_32(reader, shared_values)? { 0 => crate::data::SumWithVariants::VariantOne(crate::data::transient_0::decode_variant_one(reader, shared_values)?), 1 => crate::data::SumWithVariants::VariantTwo(crate::data::transient_0::decode_variant_two(reader, shared_values)?), @@ -210,27 +288,27 @@ pub fn decode_sum_with_variants(reader: &mut impl std::io::Read, shared_values: }) } -pub fn encode_variant_one(value: &crate::data::VariantOne, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_variant_one(value: &crate::data::VariantOne, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { crate::transient_0::encode_int_32(&value.a, writer, shared_values)?; ::std::io::Result::Ok(()) } -pub fn decode_variant_one(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::VariantOne> { +pub fn decode_variant_one(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::VariantOne> { let a = crate::transient_0::decode_int_32(reader, shared_values)?; ::std::io::Result::Ok(crate::data::VariantOne { a: a }) } -pub fn encode_variant_two(value: &crate::data::VariantTwo, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_variant_two(value: &crate::data::VariantTwo, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { crate::transient_0::encode_int_64(&value.a, writer, shared_values)?; ::std::io::Result::Ok(()) } -pub fn decode_variant_two(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::VariantTwo> { +pub fn decode_variant_two(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::VariantTwo> { let a = crate::transient_0::decode_int_64(reader, shared_values)?; ::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::<()> { +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)?; @@ -244,7 +322,7 @@ pub fn encode_sum_with_boxed_variants(value: &crate::data::SumWithBoxedVariants, ::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::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::SumWithBoxedVariants> { +pub fn decode_sum_with_boxed_variants(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::SumWithBoxedVariants> { ::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)?)), @@ -252,29 +330,29 @@ pub fn decode_sum_with_boxed_variants(reader: &mut impl std::io::Read, shared_va }) } -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::<()> { +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)?; ::std::io::Result::Ok(()) } -pub fn decode_struct_with_sum(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithSum> { +pub fn decode_struct_with_sum(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithSum> { let inner = crate::data::transient_0::decode_sum_with_variants(reader, shared_values)?; let b = crate::transient_0::decode_int_32(reader, shared_values)?; ::std::io::Result::Ok(crate::data::StructWithSum { inner: inner, b: b }) } -pub fn encode_struct_with_native(value: &crate::data::StructWithNative, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_native(value: &crate::data::StructWithNative, 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_native(&value.a, writer, shared_values)?; ::std::io::Result::Ok(()) } -pub fn decode_struct_with_native(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithNative> { +pub fn decode_struct_with_native(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithNative> { let a = crate::data::transient_0::decode_native(reader, shared_values)?; ::std::io::Result::Ok(crate::data::StructWithNative { a: a }) } -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::<()> { +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::<()> { 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(()) @@ -320,7 +398,7 @@ pub fn encode_struct_with_generic_native(value: &crate::data::StructWithGenericN ::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::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithGenericNative> { +pub fn decode_struct_with_generic_native(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithGenericNative> { 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)?; @@ -340,17 +418,17 @@ pub fn decode_struct_with_generic_native(reader: &mut impl std::io::Read, shared ::std::io::Result::Ok(crate::data::StructWithGenericNative { a: a, b: b }) } -pub fn encode_struct_with_box(value: &crate::data::StructWithBox, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_box(value: &crate::data::StructWithBox, 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_struct_with_int_32((&value.inner).as_ref(), writer, shared_values)?; ::std::io::Result::Ok(()) } -pub fn decode_struct_with_box(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithBox> { +pub fn decode_struct_with_box(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithBox> { let inner = ::std::boxed::Box::new(crate::data::transient_0::decode_struct_with_int_32(reader, shared_values)?); ::std::io::Result::Ok(crate::data::StructWithBox { inner: inner }) } -pub fn encode_struct_with_list_of_shared(value: &crate::data::StructWithListOfShared, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_list_of_shared(value: &crate::data::StructWithListOfShared, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { { crate::transient_0::encode_int_64(&(((&value.inner).len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?, writer, shared_values)?; for element in &value.inner { @@ -373,7 +451,7 @@ pub fn encode_struct_with_list_of_shared(value: &crate::data::StructWithListOfSh ::std::io::Result::Ok(()) } -pub fn decode_struct_with_list_of_shared(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithListOfShared> { +pub fn decode_struct_with_list_of_shared(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithListOfShared> { let inner = { let len = crate::transient_0::decode_int_64(reader, shared_values)?; let mut elements = ::std::vec::Vec::with_capacity((len.try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?); @@ -394,7 +472,7 @@ pub fn decode_struct_with_list_of_shared(reader: &mut impl std::io::Read, shared ::std::io::Result::Ok(crate::data::StructWithListOfShared { inner: inner }) } -pub fn encode_struct_with_different_shared_types(value: &crate::data::StructWithDifferentSharedTypes, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_different_shared_types(value: &crate::data::StructWithDifferentSharedTypes, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { { let ptr = ::std::sync::Arc::as_ptr(&&value.a) as ::core::primitive::usize; match (shared_values.get(&ptr)).copied() { @@ -440,7 +518,7 @@ pub fn encode_struct_with_different_shared_types(value: &crate::data::StructWith ::std::io::Result::Ok(()) } -pub fn decode_struct_with_different_shared_types(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithDifferentSharedTypes> { +pub fn decode_struct_with_different_shared_types(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithDifferentSharedTypes> { let a = { let id = crate::transient_0::decode_int_64(reader, shared_values)?; if id < ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))? { @@ -474,7 +552,7 @@ pub fn decode_struct_with_different_shared_types(reader: &mut impl std::io::Read ::std::io::Result::Ok(crate::data::StructWithDifferentSharedTypes { a: a, b: b, c: c }) } -pub fn encode_struct_with_shared_sum_and_variant(value: &crate::data::StructWithSharedSumAndVariant, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_struct_with_shared_sum_and_variant(value: &crate::data::StructWithSharedSumAndVariant, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { { let ptr = ::std::sync::Arc::as_ptr(&&value.a) as ::core::primitive::usize; match (shared_values.get(&ptr)).copied() { @@ -506,7 +584,7 @@ pub fn encode_struct_with_shared_sum_and_variant(value: &crate::data::StructWith ::std::io::Result::Ok(()) } -pub fn decode_struct_with_shared_sum_and_variant(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithSharedSumAndVariant> { +pub fn decode_struct_with_shared_sum_and_variant(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithSharedSumAndVariant> { let a = { let id = crate::transient_0::decode_int_64(reader, shared_values)?; if id < ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))? { diff --git a/examples/16-transient-0/output/rust/src/gen/transient_0.rs b/examples/16-transient-0/output/rust/src/gen/transient_0.rs index b65ab95..f9538ca 100644 --- a/examples/16-transient-0/output/rust/src/gen/transient_0.rs +++ b/examples/16-transient-0/output/rust/src/gen/transient_0.rs @@ -4,7 +4,7 @@ pub type Encode<T, TWrite: ::std::io::Write> = fn(&T, &mut TWrite, &mut ::std::c pub type Decode<TRead: ::std::io::Read, T> = fn(&mut TRead, &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<T>; -pub fn encode_bool(value: &::core::primitive::bool, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_bool(value: &::core::primitive::bool, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { if *value { writer.write_all(&1u8.to_le_bytes())?; } else { @@ -13,7 +13,7 @@ pub fn encode_bool(value: &::core::primitive::bool, writer: &mut impl std::io::W ::std::io::Result::Ok(()) } -pub fn decode_bool(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::core::primitive::bool> { +pub fn decode_bool(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::core::primitive::bool> { let int_value = { let bytes = { let mut bytes = [0; 1]; @@ -29,12 +29,12 @@ pub fn decode_bool(reader: &mut impl std::io::Read, shared_values: &mut ::std::v }) } -pub fn encode_int_8(value: &::core::primitive::i8, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_int_8(value: &::core::primitive::i8, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { writer.write_all(&value.to_le_bytes())?; ::std::io::Result::Ok(()) } -pub fn decode_int_8(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::core::primitive::i8> { +pub fn decode_int_8(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::core::primitive::i8> { let bytes = { let mut bytes = [0; 1]; reader.read_exact(&mut bytes)?; @@ -43,12 +43,12 @@ pub fn decode_int_8(reader: &mut impl std::io::Read, shared_values: &mut ::std:: ::std::io::Result::Ok(::core::primitive::i8::from_le_bytes(bytes)) } -pub fn encode_int_32(value: &::core::primitive::i32, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_int_32(value: &::core::primitive::i32, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { writer.write_all(&value.to_le_bytes())?; ::std::io::Result::Ok(()) } -pub fn decode_int_32(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::core::primitive::i32> { +pub fn decode_int_32(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::core::primitive::i32> { let bytes = { let mut bytes = [0; 4]; reader.read_exact(&mut bytes)?; @@ -57,12 +57,12 @@ pub fn decode_int_32(reader: &mut impl std::io::Read, shared_values: &mut ::std: ::std::io::Result::Ok(::core::primitive::i32::from_le_bytes(bytes)) } -pub fn encode_int_64(value: &::core::primitive::i64, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_int_64(value: &::core::primitive::i64, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { writer.write_all(&value.to_le_bytes())?; ::std::io::Result::Ok(()) } -pub fn decode_int_64(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::core::primitive::i64> { +pub fn decode_int_64(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::core::primitive::i64> { let bytes = { let mut bytes = [0; 8]; reader.read_exact(&mut bytes)?; @@ -71,13 +71,13 @@ pub fn decode_int_64(reader: &mut impl std::io::Read, shared_values: &mut ::std: ::std::io::Result::Ok(::core::primitive::i64::from_le_bytes(bytes)) } -pub fn encode_string(value: &::std::string::String, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { +pub fn encode_string(value: &::std::string::String, writer: &mut impl ::std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> { crate::transient_0::encode_int_64(&((value.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?, writer, shared_values)?; writer.write_all(value.as_bytes())?; ::std::io::Result::Ok(()) } -pub fn decode_string(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::std::string::String> { +pub fn decode_string(reader: &mut impl ::std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::std::string::String> { let len = crate::transient_0::decode_int_64(reader, shared_values)?; let bytes = { let mut bytes = vec![0u8; (len.try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?]; diff --git a/examples/16-transient-0/output/rust/src/lib.rs b/examples/16-transient-0/output/rust/src/lib.rs index a51afff..670389a 100644 --- a/examples/16-transient-0/output/rust/src/lib.rs +++ b/examples/16-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, GenericNative, Native, StructSingleton, StructWithBool, StructWithBox, StructWithDifferentSharedTypes, StructWithEnum, StructWithGenericNative, StructWithInt8, StructWithInt32, StructWithInt64, StructWithList, StructWithListOfShared, StructWithNative, StructWithOption, StructWithSharedSumAndVariant, StructWithString, StructWithStruct, StructWithSum, SumWithBoxedVariants, SumWithVariants, VariantOne, VariantTwo }; + use super::data::{EnumWithVariants, GenericNative, GenericStruct, Native, StructSingleton, StructWithBool, StructWithBox, StructWithDifferentSharedTypes, StructWithEnum, StructWithGenericNative, StructWithGenericStruct, StructWithInt8, StructWithInt32, StructWithInt64, StructWithList, StructWithListOfShared, StructWithNative, StructWithOption, StructWithSharedSumAndVariant, StructWithString, StructWithStruct, StructWithSum, SumWithBoxedVariants, SumWithVariants, VariantOne, VariantTwo }; #[test] fn struct_singleton() { @@ -95,6 +95,27 @@ mod test { } #[test] + fn struct_with_generic_struct() { + let value = StructWithGenericStruct { + a: GenericStruct { a: 10, b: "x1".to_string() }, + b: GenericStruct { + a: Some("x2".to_string()), + b: GenericStruct { + a: Some("x3".to_string()), + b: GenericStruct { a: "x4".to_string(), b: "x5".to_string() }, + }, + }, + }; + + assert_round_trip_encoding( + "StructWithGenericStruct", + value, + super::data::transient_0::encode_struct_with_generic_struct, + super::data::transient_0::decode_struct_with_generic_struct, + ); + } + + #[test] fn struct_with_list() { let value = StructWithList { a: vec![10, 25], diff --git a/examples/16-transient-0/src/data.hob b/examples/16-transient-0/src/data.hob index df96916..ed93768 100644 --- a/examples/16-transient-0/src/data.hob +++ b/examples/16-transient-0/src/data.hob @@ -32,6 +32,16 @@ struct StructWithStruct { field c: Int32; } +struct GenericStruct[A, B] { + field a: A; + field b: B; +} + +struct StructWithGenericStruct { + field a: GenericStruct[Int32, String]; + field b: GenericStruct[Option[String], GenericStruct[Option[String], GenericStruct[String, String]]]; +} + struct StructWithList { field a: List[Int64]; field b: List[StructWithInt32]; diff --git a/hobgoblin/src/output/lang/rust/ast.hob b/hobgoblin/src/output/lang/rust/ast.hob index 7f7c8ff..deb651a 100644 --- a/hobgoblin/src/output/lang/rust/ast.hob +++ b/hobgoblin/src/output/lang/rust/ast.hob @@ -23,6 +23,7 @@ sum RustItem { struct RustFunction { field visibility: Option[RustVisibility]; field name: RustIdentifier; + field typeParams: List[RustTypeParam]; field params: List[RustFunctionParam]; field returnType: Option[RustType]; field body: Option[RustBlockExpression]; diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedStructDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedStructDefinitionNode.java index c956e2c..f747e44 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedStructDefinitionNode.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedStructDefinitionNode.java @@ -14,16 +14,6 @@ public record TypedStructDefinitionNode( DocComment docComment, Source source ) implements TypedNamespaceStatementNode { - public SimpleStructType typeOrThrow() { - return switch (typeOrConstructor) { - case TypeOrConstructor.Constructor<SimpleStructType> constructor -> - throw new UnsupportedOperationException("TODO"); - - case TypeOrConstructor.Type<SimpleStructType> type -> - type.value(); - }; - } - public String name() { return this.typeOrConstructor.name(); } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java index 52539ce..be42c08 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java @@ -358,7 +358,7 @@ public class JavaTransient0Generator implements Generator { } private JavaMethodDeclaration generateEncodeIntMethod( - Type type, + SimpleType type, int bits ) { var statements = byteIndicesInBits(bits) @@ -695,7 +695,7 @@ public class JavaTransient0Generator implements Generator { TypedStructDefinitionNode structDefinition, Context context ) { - Function<JavaTypeRef, JavaBlock> decodeBody = structJavaTypeRef -> new JavaBlock( + Function<JavaTypeRef, JavaBlock> decodeBody = structJavaTypeRef -> new JavaBlock( structDefinition.fields().isEmpty() ? List.of(new JavaReturn( new JavaStaticFieldAccess(structJavaTypeRef, JavaGenerator.INSTANCE_FIELD_NAME) @@ -827,7 +827,7 @@ public class JavaTransient0Generator implements Generator { } private JavaMethodDeclaration generateEncodeMethod( - Type type, + SimpleType type, JavaBlock body ) { var javaTypeRef = this.javaGenerator.generateTypeRef(type); @@ -1035,7 +1035,9 @@ public class JavaTransient0Generator implements Generator { } case TypeParam _ -> { - throw new UnsupportedOperationException("TODO"); + // In theory, I think this should never happen: we should only + // be generating encode method refs for fully instantiated types. + throw new IllegalArgumentException("cannot generate encode method ref for type param"); } }; } @@ -1169,7 +1171,9 @@ public class JavaTransient0Generator implements Generator { } case TypeParam _ -> { - throw new UnsupportedOperationException("TODO"); + // In theory, I think this should never happen: we should only + // be generating decode method refs for fully instantiated types. + throw new IllegalArgumentException("cannot generate decode method ref for type param"); } }; } 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 421366f..d6aa888 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 @@ -31,6 +31,8 @@ public class RustTransient0Generator implements Generator { private static final RustIdentifier READER_NAME = RustIdentifier.of("reader"); private static final RustIdentifier WRITER_NAME = RustIdentifier.of("writer"); private static final RustIdentifier SHARED_VALUES_NAME = RustIdentifier.of("shared_values"); + private static final RustIdentifier ENCODE_TYPE_NAME = RustIdentifier.of("Encode"); + private static final RustIdentifier DECODE_TYPE_NAME = RustIdentifier.of("Decode"); public static OutputConfig parseGeneratorConfig( Path projectRoot, @@ -67,7 +69,7 @@ public class RustTransient0Generator implements Generator { } private void generateBuiltins() throws IOException { - var rustModuleName = this.generateTransient0ModuleName(NamespaceName.of()); + var rustModuleName = builtinsModuleName(); var rustModule = new RustModule( rustModuleName, List.of( @@ -89,12 +91,16 @@ public class RustTransient0Generator implements Generator { this.rustGenerator.write(rustModule); } + private ArrayList<RustIdentifier> builtinsModuleName() { + return this.generateTransient0ModuleName(NamespaceName.of()); + } + private RustItem generateEncodeType() { var valueType = RustIdentifier.of("T"); var writeType = RustIdentifier.of("TWrite"); return new RustTypeAlias( Optional.of(RustVisibility.PUB), - RustIdentifier.of("Encode"), + ENCODE_TYPE_NAME, List.of( new RustTypeParam(valueType, List.of()), new RustTypeParam(writeType, List.of(RustTypes.IO_WRITE)) @@ -110,12 +116,18 @@ public class RustTransient0Generator implements Generator { ); } + private RustType encodeType(RustType valueType, RustType writeType) { + return RustPath.crate(builtinsModuleName()) + .addSegment(RustPathSegment.of(ENCODE_TYPE_NAME)) + .withArgs(List.of(valueType, writeType)); + } + private RustItem generateDecodeType() { var valueType = RustIdentifier.of("T"); var readType = RustIdentifier.of("TRead"); return new RustTypeAlias( Optional.of(RustVisibility.PUB), - RustIdentifier.of("Decode"), + DECODE_TYPE_NAME, List.of( new RustTypeParam(readType, List.of(RustTypes.IO_READ)), new RustTypeParam(valueType, List.of()) @@ -130,6 +142,12 @@ public class RustTransient0Generator implements Generator { ); } + private RustType decodeType(RustType readType, RustType valueType) { + return RustPath.crate(builtinsModuleName()) + .addSegment(RustPathSegment.of(DECODE_TYPE_NAME)) + .withArgs(List.of(readType, valueType)); + } + private RustItem generateEncodeBoolFunction() { return generateEncodeFunction( NativeTypes.BOOL, @@ -442,49 +460,71 @@ public class RustTransient0Generator implements Generator { } private RustItem generateEncodeStructFunction(TypedStructDefinitionNode structDefinition) { - return generateEncodeFunction( - structDefinition.typeOrThrow(), - structDefinition.fields().orElse(List.of()).stream() - .map(field -> generateEncode( - new RustPrefixExpression( - RustPrefixOperator.BORROW, - new RustFieldExpression( - RustPath.of(VALUE_NAME), - this.rustGenerator.generateFieldName(field.name()) - ) - ), - field.type().value() - )) - .toList() - ); + var fields = structDefinition.fields().orElse(List.of()); + + var rustBody = fields.stream() + .map(field -> generateEncode( + new RustPrefixExpression( + RustPrefixOperator.BORROW, + new RustFieldExpression( + RustPath.of(VALUE_NAME), + this.rustGenerator.generateFieldName(field.name()) + ) + ), + field.type().value() + )) + .toList(); + + return switch (structDefinition.typeOrConstructor()) { + case TypeOrConstructor.Constructor<SimpleStructType> constructor -> + generateEncodeFunction( + constructor.value(), + rustBody + ); + + case TypeOrConstructor.Type<SimpleStructType> type -> + generateEncodeFunction( + type.value(), + rustBody + ); + }; } private RustItem generateDecodeStructFunction(TypedStructDefinitionNode structDefinition) { - var rustType = this.rustGenerator.generateRustTypeExpression(structDefinition.typeOrThrow()); - - return generateDecodeFunction( - structDefinition.typeOrThrow(), - structDefinition.fields().isEmpty() - ? new RustBlockExpression(List.of(), Optional.of(rustType)) - : new RustBlockExpression( + Function<RustPath, RustBlockExpression> decodeBody = rustType -> structDefinition.fields().isEmpty() + ? new RustBlockExpression(List.of(), Optional.of(rustType)) + : new RustBlockExpression( + structDefinition.fields().get().stream() + .<RustStatement>map(field -> new RustLetStatement( + this.rustGenerator.generateFieldName(field.name()), + false, + generateDecode(field.type().value()) + )) + .toList(), + Optional.of(new RustStructExpression( + rustType, structDefinition.fields().get().stream() - .<RustStatement>map(field -> new RustLetStatement( + .map(field -> new RustStructExprField( this.rustGenerator.generateFieldName(field.name()), - false, - generateDecode(field.type().value()) + RustPath.of(this.rustGenerator.generateFieldName(field.name())) )) - .toList(), - Optional.of(new RustStructExpression( - rustType, - structDefinition.fields().get().stream() - .map(field -> new RustStructExprField( - this.rustGenerator.generateFieldName(field.name()), - RustPath.of(this.rustGenerator.generateFieldName(field.name())) - )) - .toList() - )) - ) - ); + .toList() + )) + ); + + return switch (structDefinition.typeOrConstructor()) { + case TypeOrConstructor.Constructor<SimpleStructType> constructor -> + generateDecodeFunction( + constructor.value(), + decodeBody + ); + + case TypeOrConstructor.Type<SimpleStructType> type -> + generateDecodeFunction( + type.value(), + decodeBody.apply(this.rustGenerator.generateRustTypeExpression(type.value())) + ); + }; } private RustItem generateEncodeSumFunction( @@ -563,7 +603,7 @@ public class RustTransient0Generator implements Generator { } private RustItem generateEncodeFunction( - Type type, + SimpleType type, List<RustStatement> body ) { var rustType = this.rustGenerator.generateRustTypeExpression(type); @@ -571,7 +611,69 @@ public class RustTransient0Generator implements Generator { return new RustFunction( Optional.of(RustVisibility.PUB), encodeMethodName(type), - generateEncodeParams(rustType), + List.of(), + generateEncodeParams(rustType, new RustImplTraitType(RustTypes.IO_WRITE)), + Optional.of( + RustTypes.ioResult(RustTypes.UNIT) + ), + Optional.of(new RustBlockExpression( + body, + Optional.of( + new RustCallExpression( + RustTypes.IO_RESULT_OK, + List.of(new RustTupleExpression(List.of())) + ) + ) + )) + ); + } + + private RustItem generateEncodeFunction( + TypeConstructor<?> constructor, + List<RustStatement> body + ) { + // TODO: need to handle collisions with hobgoblin type params? (similarly for decode) + var writeRustTypeParam = new RustTypeParam( + RustIdentifier.of("TWrite"), + List.of(RustTypes.IO_WRITE) + ); + + var encodeRustTypeParams = constructor.params().stream() + .map(typeParam -> new RustTypeParam( + this.rustGenerator.generateTypeName(typeParam.name()), + List.of() + )) + .toList(); + + var rustTypeArgs = encodeRustTypeParams.stream() + .<RustType>map(rustTypeParam -> RustPath.of(rustTypeParam.name())) + .toList(); + + var rustType = this.rustGenerator.generateRustTypeExpression(constructor.genericType()) + .withArgs(rustTypeArgs); + + var typeArgEncodeParams = IntStream.range(0, constructor.params().size()) + .mapToObj(typeParamIndex -> { + var typeParam = constructor.params().get(typeParamIndex); + var rustTypeParam = encodeRustTypeParams.get(typeParamIndex); + return new RustFunctionParam( + generateEncodeVariableName(typeParam), + encodeType(RustPath.of(rustTypeParam.name()), RustPath.of(writeRustTypeParam.name())) + ); + }) + .toList(); + + return new RustFunction( + Optional.of(RustVisibility.PUB), + encodeMethodName(constructor.genericType()), + Lists.concat(List.of( + List.of(writeRustTypeParam), + encodeRustTypeParams + )), + Lists.concat(List.of( + generateEncodeParams(rustType, RustPath.of(writeRustTypeParam.name())), + typeArgEncodeParams + )), Optional.of( RustTypes.ioResult(RustTypes.UNIT) ), @@ -587,10 +689,10 @@ public class RustTransient0Generator implements Generator { ); } - private static List<RustFunctionParam> generateEncodeParams(RustPath rustType) { + private static List<RustFunctionParam> generateEncodeParams(RustPath rustType, RustType writeType) { 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(WRITER_NAME, new RustMutableReferenceType(writeType)), new RustFunctionParam(SHARED_VALUES_NAME, encoderSharedValuesType()) ); } @@ -601,8 +703,12 @@ public class RustTransient0Generator implements Generator { ); } + private RustIdentifier generateEncodeVariableName(TypeParam typeParam) { + return this.rustGenerator.generateFieldName("encode" + typeParam.name()); + } + private RustItem generateDecodeFunction( - Type type, + SimpleType type, RustBlockExpression body ) { var rustType = this.rustGenerator.generateRustTypeExpression(type); @@ -610,7 +716,63 @@ public class RustTransient0Generator implements Generator { return new RustFunction( Optional.of(RustVisibility.PUB), decodeMethodName(type), - generateDecodeParams(), + List.of(), + generateDecodeParams(new RustImplTraitType(RustTypes.IO_READ)), + Optional.of(RustTypes.ioResult(rustType)), + Optional.of(new RustBlockExpression( + body.statements(), + body.finalOperand().map(finalOperand -> new RustCallExpression(RustTypes.IO_RESULT_OK, List.of(finalOperand))) + )) + ); + } + + private RustItem generateDecodeFunction( + TypeConstructor<?> constructor, + Function<RustPath, RustBlockExpression> generateBody + ) { + var readTypeParam = new RustTypeParam( + RustIdentifier.of("TRead"), + List.of(RustTypes.IO_READ) + ); + + var decodeRustTypeParams = constructor.params().stream() + .map(typeParam -> new RustTypeParam( + this.rustGenerator.generateTypeName(typeParam.name()), + List.of() + )) + .toList(); + + var rustTypeArgs = decodeRustTypeParams.stream() + .<RustType>map(rustTypeParam -> RustPath.of(rustTypeParam.name())) + .toList(); + + var rustType = this.rustGenerator.generateRustTypeExpression(constructor.genericType()) + .withArgs(rustTypeArgs); + + var typeArgDecoderParams = IntStream.range(0, constructor.params().size()) + .mapToObj(typeParamIndex -> { + var typeParam = constructor.params().get(typeParamIndex); + var rustTypeParam = decodeRustTypeParams.get(typeParamIndex); + return new RustFunctionParam( + generateDecodeVariableName(typeParam), + decodeType(RustPath.of(readTypeParam.name()), RustPath.of(rustTypeParam.name())) + ); + }) + .toList(); + + var body = generateBody.apply(rustType); + + return new RustFunction( + Optional.of(RustVisibility.PUB), + decodeMethodName(constructor.genericType()), + Lists.concat(List.of( + List.of(readTypeParam), + decodeRustTypeParams + )), + Lists.concat(List.of( + generateDecodeParams(RustPath.of(readTypeParam.name())), + typeArgDecoderParams + )), Optional.of(RustTypes.ioResult(rustType)), Optional.of(new RustBlockExpression( body.statements(), @@ -619,9 +781,9 @@ public class RustTransient0Generator implements Generator { ); } - private static List<RustFunctionParam> generateDecodeParams() { + private static List<RustFunctionParam> generateDecodeParams(RustType readType) { return List.of( - new RustFunctionParam(READER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Read")))), + new RustFunctionParam(READER_NAME, new RustMutableReferenceType(readType)), new RustFunctionParam(SHARED_VALUES_NAME, decoderSharedValuesType()) ); } @@ -632,6 +794,10 @@ public class RustTransient0Generator implements Generator { ); } + private RustIdentifier generateDecodeVariableName(TypeParam typeParam) { + return this.rustGenerator.generateFieldName("decode" + typeParam.name()); + } + private RustStatement generateEncode(RustExpression value, Type type) { return switch (type) { case ConstructedType constructedType -> { @@ -651,7 +817,8 @@ public class RustTransient0Generator implements Generator { constructedType.args().stream() .<RustExpression>map(typeArg -> new RustClosureExpression( RustGenerator.functionParamsToClosureParams(generateEncodeParams( - this.rustGenerator.generateRustTypeExpression(typeArg) + this.rustGenerator.generateRustTypeExpression(typeArg), + new RustImplTraitType(RustTypes.IO_WRITE) )), new RustBlockExpression( List.of(generateEncode(RustPath.of(VALUE_NAME), typeArg)), @@ -674,8 +841,11 @@ public class RustTransient0Generator implements Generator { yield new RustExpressionStatement(generateTodo()); } - case TypeParam _ -> { - yield new RustExpressionStatement(generateTodo()); + case TypeParam typeParam -> { + yield new RustExpressionStatement(new RustTryPropagationExpression(new RustCallExpression( + RustPath.of(generateEncodeVariableName(typeParam)), + List.of(value, RustPath.of(WRITER_NAME), RustPath.of(SHARED_VALUES_NAME)) + ))); } }; } @@ -697,7 +867,9 @@ public class RustTransient0Generator implements Generator { constructedType, constructedType.args().stream() .<RustExpression>map(typeArg -> new RustClosureExpression( - RustGenerator.functionParamsToClosureParams(generateDecodeParams()), + RustGenerator.functionParamsToClosureParams( + generateDecodeParams(new RustImplTraitType(RustTypes.IO_READ)) + ), new RustCallExpression( RustTypes.IO_RESULT_OK, List.of(generateDecode(typeArg)) @@ -717,8 +889,11 @@ public class RustTransient0Generator implements Generator { yield generateTodo(); } - case TypeParam _ -> { - yield generateTodo(); + case TypeParam typeParam -> { + yield new RustTryPropagationExpression(new RustCallExpression( + RustPath.of(generateDecodeVariableName(typeParam)), + List.of(RustPath.of(READER_NAME), RustPath.of(SHARED_VALUES_NAME)) + )); } }; } 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 a5c2118..4df01d1 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 @@ -221,6 +221,7 @@ public class RustTypesGenerator implements Generator { new RustFunction( Optional.empty(), new RustIdentifier("from"), + List.of(), List.of(new RustFunctionParam(innerValueName, fromRustType)), Optional.of(RustPath.selfType()), Optional.of(new RustBlockExpression( 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 index da534b2..df8aa8c 100644 --- 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 @@ -103,6 +103,7 @@ public class RustWriter implements AutoCloseable { this.writer.write("fn "); this.writeIdentifier(function.name()); + this.writeTypeParams(function.typeParams()); this.writer.write("("); writeWithSeparator( diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustFunction.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustFunction.java index 438dfa8..d5ebb38 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustFunction.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustFunction.java @@ -8,79 +8,97 @@ package org.zwobble.hobgoblin.compiler.output.lang.rust.ast; public record RustFunction( java.util.Optional<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustVisibility> visibility, org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name, + java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam> typeParams, java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionParam> params, java.util.Optional<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType> returnType, java.util.Optional<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustBlockExpression> body ) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem, org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustAssociatedItem { public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder arbitrary() { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(java.util.Optional.empty(), org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.arbitrary().build(), java.util.List.of(), java.util.Optional.empty(), java.util.Optional.empty()); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(java.util.Optional.empty(), org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.arbitrary().build(), java.util.List.of(), java.util.List.of(), java.util.Optional.empty(), java.util.Optional.empty()); } public record Builder( java.util.Optional<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustVisibility> visibility, org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name, + java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam> typeParams, java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionParam> params, java.util.Optional<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType> returnType, java.util.Optional<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustBlockExpression> body ) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustItem.Builder, org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustAssociatedItem.Builder { public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction build() { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction(visibility, name, params, returnType, body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction(visibility, name, typeParams, params, returnType, body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withVisibility(java.util.Optional<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustVisibility> visibility) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, params, returnType, body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withVisibility(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustVisibility visibility) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(java.util.Optional.of(visibility), name, params, returnType, body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(java.util.Optional.of(visibility), name, typeParams, params, returnType, body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier name) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, params, returnType, body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier.Builder name) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name.build(), params, returnType, body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name.build(), typeParams, params, returnType, body); + } + + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withTypeParams(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam> typeParams) { + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, body); + } + + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder addTypeParam(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam typeParam) { + var typeParams = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam>(this.typeParams); + typeParams.add(typeParam); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, body); + } + + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder addTypeParam(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam.Builder typeParam) { + var typeParams = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam>(this.typeParams); + typeParams.add(typeParam.build()); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withParams(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionParam> params) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, params, returnType, body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder addParam(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionParam param) { var params = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionParam>(this.params); params.add(param); - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, params, returnType, body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder addParam(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionParam.Builder param) { var params = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionParam>(this.params); params.add(param.build()); - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, params, returnType, body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withReturnType(java.util.Optional<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType> returnType) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, params, returnType, body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withReturnType(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType returnType) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, params, java.util.Optional.of(returnType), body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, java.util.Optional.of(returnType), body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withReturnType(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType.Builder returnType) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, params, java.util.Optional.of(returnType.build()), body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, java.util.Optional.of(returnType.build()), body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withBody(java.util.Optional<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustBlockExpression> body) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, params, returnType, body); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, body); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withBody(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustBlockExpression body) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, params, returnType, java.util.Optional.of(body)); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, java.util.Optional.of(body)); } public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder withBody(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustBlockExpression.Builder body) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, params, returnType, java.util.Optional.of(body.build())); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder(visibility, name, typeParams, params, returnType, java.util.Optional.of(body.build())); } // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction.Builder body 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 index feabc12..15bb5c8 100644 --- 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 @@ -64,6 +64,20 @@ public class RustWriterTests { } @Test + public void functionWithTypeParams() throws IOException { + var rust = RustFunction.arbitrary() + .withName(new RustIdentifier("f")) + .addTypeParam(RustTypeParam.arbitrary().withName(RustIdentifier.of("T1"))) + .addTypeParam(RustTypeParam.arbitrary().withName(RustIdentifier.of("T2"))) + .build(); + + var string = write(writer -> writer.writeAssociatedItem(rust)); + + assertThat(string, equalTo(""" + fn f<T1, T2>();""")); + } + + @Test public void functionWithParams() throws IOException { var rust = RustFunction.arbitrary() .withName(new RustIdentifier("area")) diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustFunctionMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustFunctionMatcher.java index 3b07f1d..2254ad9 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustFunctionMatcher.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustFunctionMatcher.java @@ -42,6 +42,12 @@ public final class RustFunctionMatcher implements org.zwobble.precisely.Matcher< return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionMatcher(submatchers); } + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionMatcher withTypeParams(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypeParam>> typeParams) { + var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction>>(this.submatchers); + submatchers.add(org.zwobble.precisely.Matchers.has("typeParams", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction::typeParams, typeParams)); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionMatcher(submatchers); + } + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionMatcher withParams(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunctionParam>> params) { var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction>>(this.submatchers); submatchers.add(org.zwobble.precisely.Matchers.has("params", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustFunction::params, params)); |
