diff options
3 files changed, 113 insertions, 7 deletions
diff --git a/examples/10-transient-0/output/rust/src/gen/data/transient_0.rs b/examples/10-transient-0/output/rust/src/gen/data/transient_0.rs index bfc7c75..f8e9be0 100644 --- a/examples/10-transient-0/output/rust/src/gen/data/transient_0.rs +++ b/examples/10-transient-0/output/rust/src/gen/data/transient_0.rs @@ -73,14 +73,38 @@ pub fn decode_inner_struct(reader: &mut impl std::io::Read) -> ::std::io::Result } pub fn encode_struct_with_list(value: &crate::data::StructWithList, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> { - todo!(); - todo!(); + { + crate::transient_0::encode_int_64(&(((&value.a).len()).try_into()).unwrap(), writer)?; + }; + for element in &value.a { + crate::transient_0::encode_int_64(element, writer)?; + }; + { + crate::transient_0::encode_int_64(&(((&value.b).len()).try_into()).unwrap(), writer)?; + }; + for element in &value.b { + crate::data::transient_0::encode_inner_struct(element, writer)?; + }; ::std::io::Result::Ok(()) } pub fn decode_struct_with_list(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithList> { - let a = todo!(); - let b = todo!(); + let a = { + let len = crate::transient_0::decode_int_64(reader)?; + let mut elements = ::std::vec::Vec::with_capacity((len.try_into()).unwrap()); + for element_index in 0..len { + elements.push(crate::transient_0::decode_int_64(reader)?); + }; + elements + }; + let b = { + let len = crate::transient_0::decode_int_64(reader)?; + let mut elements = ::std::vec::Vec::with_capacity((len.try_into()).unwrap()); + for element_index in 0..len { + elements.push(crate::data::transient_0::decode_inner_struct(reader)?); + }; + elements + }; std::io::Result::Ok(crate::data::StructWithList { a: a, b: b }) } diff --git a/examples/10-transient-0/output/rust/src/lib.rs b/examples/10-transient-0/output/rust/src/lib.rs index 6ecb19e..a06f73e 100644 --- a/examples/10-transient-0/output/rust/src/lib.rs +++ b/examples/10-transient-0/output/rust/src/lib.rs @@ -4,7 +4,7 @@ pub mod transient_0; #[cfg(test)] mod test { use std::io::Cursor; - use super::data::{InnerStruct, OuterStruct, StructWithBool, StructWithInt32, StructWithInt64, StructWithString}; + use super::data::{InnerStruct, OuterStruct, StructWithBool, StructWithInt32, StructWithInt64, StructWithList, StructWithString}; #[test] fn struct_with_bool() { @@ -61,6 +61,24 @@ mod test { ); } + #[test] + fn struct_with_list() { + let value = StructWithList { + a: vec![10, 25], + b: vec![ + InnerStruct { a: 42, b: 47 }, + InnerStruct { a: 52, b: 57 }, + InnerStruct { a: 62, b: 67 }, + ], + }; + + assert_round_trip_encoding( + value, + super::data::transient_0::encode_struct_with_list, + super::data::transient_0::decode_struct_with_list, + ); + } + fn assert_round_trip_encoding<T: std::cmp::PartialEq + std::fmt::Debug>( value: T, encode: impl Fn(&T, &mut Cursor<Vec<u8>>) -> std::io::Result<()>, 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 6d24c0a..a17ae6b 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 @@ -403,7 +403,11 @@ public class RustTransient0Generator implements Generator { private List<RustStatement> generateEncode(RustExpression value, Type type) { return switch (type) { case ConstructedNativeType constructedNativeType -> { - yield List.of(new RustExpressionStatement(generateTodo())); + if (constructedNativeType.constructor().equals(NativeTypes.LIST)) { + yield generateEncodeList(value, constructedNativeType.args().getFirst()); + } else { + yield List.of(new RustExpressionStatement(generateTodo())); + } } case EnumType enumType -> { @@ -435,7 +439,11 @@ public class RustTransient0Generator implements Generator { private RustExpression generateDecode(Type type) { return switch (type) { case ConstructedNativeType constructedNativeType -> { - yield generateTodo(); + if (constructedNativeType.constructor().equals(NativeTypes.LIST)) { + yield generateDecodeList(constructedNativeType.args().getFirst()); + } else { + yield generateTodo(); + } } case EnumType enumType -> { @@ -496,6 +504,62 @@ public class RustTransient0Generator implements Generator { )); } + private List<RustStatement> generateEncodeList(RustExpression value, Type elementType) { + var element = RustIdentifier.of("element"); + + return List.of( + new RustExpressionStatement(new RustBlockExpression( + generateEncode( + new RustPrefixExpression( + RustPrefixOperator.BORROW, + tryIntoOrUnwrap(methodCall(value, RustIdentifier.of("len"), List.of())) + ), + NativeTypes.INT_64 + ), + Optional.empty() + )), + new RustExpressionStatement(new RustIteratorLoopExpression( + element, + value, + new RustBlockExpression( + generateEncode(RustPath.of(element), elementType), + Optional.empty() + ) + )) + ); + } + + private RustExpression generateDecodeList(Type elementType) { + var length = RustIdentifier.of("len"); + var elements = RustIdentifier.of("elements"); + + return new RustBlockExpression( + List.of( + new RustLetStatement(length, false, generateDecode(NativeTypes.INT_64)), + new RustLetStatement(elements, true, new RustCallExpression( + RustPath.global("std", "vec", "Vec", "with_capacity"), + List.of(tryIntoOrUnwrap(RustPath.of(length))) + )), + new RustExpressionStatement(new RustIteratorLoopExpression( + // TODO: remove unnecessary variable + RustIdentifier.of("element_index"), + new RustRangeExpr(new RustIntegerLiteral(0, Optional.empty()), RustPath.of(length)), + new RustBlockExpression( + List.of(new RustExpressionStatement( + methodCall( + RustPath.of(elements), + RustIdentifier.of("push"), + List.of(generateDecode(elementType)) + ) + )), + Optional.empty() + ) + )) + ), + Optional.of(RustPath.of(elements)) + ); + } + private RustExpression generateWriterWrite(RustExpression valueToWrite) { return new RustTryPropagationExpression(new RustCallExpression( new RustFieldExpression( |
