summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/10-transient-0/output/rust/src/gen/data/transient_0.rs32
-rw-r--r--examples/10-transient-0/output/rust/src/lib.rs20
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java68
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(