summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-07-18 11:08:35 +0100
committerMichael Williamson <mike@zwobble.org>2026-07-18 11:08:35 +0100
commitb801471a3555e81f59e60d34707cb0fd9b0864d8 (patch)
treeab8f19016ccc1c47ae6e04b95c2eec295e254391
parent28fee7435236bd1382a9e7281c8875564c607686 (diff)
Support String values in rust-transient-0
-rw-r--r--examples/10-transient-0/output/rust/src/gen/transient_0.rs13
-rw-r--r--examples/10-transient-0/output/rust/src/lib.rs13
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java111
3 files changed, 131 insertions, 6 deletions
diff --git a/examples/10-transient-0/output/rust/src/gen/transient_0.rs b/examples/10-transient-0/output/rust/src/gen/transient_0.rs
index 68aa0eb..24f5c9c 100644
--- a/examples/10-transient-0/output/rust/src/gen/transient_0.rs
+++ b/examples/10-transient-0/output/rust/src/gen/transient_0.rs
@@ -54,10 +54,19 @@ pub fn decode_int_64(reader: &mut impl std::io::Read) -> ::std::io::Result::<::c
}
pub fn encode_string(value: &::std::string::String, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- todo!();
+ {
+ crate::transient_0::encode_int_64(&((value.len()).try_into()).unwrap(), writer)?;
+ };
+ writer.write_all(value.as_bytes())?;
::std::io::Result::Ok(())
}
pub fn decode_string(reader: &mut impl std::io::Read) -> ::std::io::Result::<::std::string::String> {
- std::io::Result::Ok(todo!())
+ let len = crate::transient_0::decode_int_64(reader)?;
+ let bytes = {
+ let mut bytes = vec![0u8; (len.try_into()).unwrap()];
+ reader.read_exact(&mut bytes)?;
+ bytes
+ };
+ std::io::Result::Ok((::std::string::String::from_utf8(bytes)).unwrap())
}
diff --git a/examples/10-transient-0/output/rust/src/lib.rs b/examples/10-transient-0/output/rust/src/lib.rs
index 75a7b47..6ecb19e 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};
+ use super::data::{InnerStruct, OuterStruct, StructWithBool, StructWithInt32, StructWithInt64, StructWithString};
#[test]
fn struct_with_bool() {
@@ -40,6 +40,17 @@ mod test {
}
#[test]
+ fn struct_with_string() {
+ let value = StructWithString { a: "abc".to_string(), b: "def".to_string() };
+
+ assert_round_trip_encoding(
+ value,
+ super::data::transient_0::encode_struct_with_string,
+ super::data::transient_0::decode_struct_with_string,
+ );
+ }
+
+ #[test]
fn nested_struct() {
let value = OuterStruct { inner: InnerStruct { a: 10, b: 25 }, c: 42 };
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 5639ca2..f5e1f25 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
@@ -215,17 +215,68 @@ public class RustTransient0Generator implements Generator {
return generateEncodeFunction(
NativeTypes.STRING,
List.of(
- new RustExpressionStatement(generateTodo())
+ new RustExpressionStatement(new RustBlockExpression(
+ generateEncode(
+ new RustPrefixExpression(
+ RustPrefixOperator.BORROW,
+ methodCall(
+ methodCall(
+ methodCall(
+ RustPath.of(VALUE_NAME),
+ RustIdentifier.of("len"),
+ List.of()
+ ),
+ RustIdentifier.of("try_into"),
+ List.of()
+ ),
+ // TODO: remove unwrap
+ RustIdentifier.of("unwrap"),
+ List.of()
+ )
+ ),
+ NativeTypes.INT_64
+ ),
+ Optional.empty()
+ )),
+ new RustExpressionStatement(generateWriterWrite(
+ methodCall(
+ RustPath.of(VALUE_NAME),
+ RustIdentifier.of("as_bytes"),
+ List.of()
+ )
+ ))
)
);
}
private RustItem generateDecodeStringFunction() {
+ var len = RustIdentifier.of("len");
+ var bytes = RustIdentifier.of("bytes");
+
return generateDecodeFunction(
NativeTypes.STRING,
new RustBlockExpression(
- List.of(),
- Optional.of(generateTodo())
+ List.of(
+ new RustLetStatement(
+ len,
+ false,
+ generateDecode(NativeTypes.INT_64)
+ ),
+ new RustLetStatement(
+ bytes,
+ false,
+ generateReaderReadExact(RustPath.of(len))
+ )
+ ),
+ Optional.of(methodCall(
+ new RustCallExpression(
+ RustPath.global("std", "string", "String", "from_utf8"),
+ List.of(RustPath.of(bytes))
+ ),
+ // TODO: remove unwrap
+ RustIdentifier.of("unwrap"),
+ List.of()
+ ))
)
);
}
@@ -494,6 +545,46 @@ public class RustTransient0Generator implements Generator {
);
}
+ private RustExpression generateReaderReadExact(RustExpression length) {
+ var bytes = RustIdentifier.of("bytes");
+
+ // TODO: extract into let
+ var lengthUsize = methodCall(
+ methodCall(
+ length,
+ RustIdentifier.of("try_into"),
+ List.of()
+ ),
+ // TODO: remove unwrap
+ RustIdentifier.of("unwrap"),
+ List.of()
+ );
+
+ return new RustBlockExpression(
+ List.of(
+ new RustLetStatement(
+ bytes,
+ true,
+ // TODO: use uninit
+ new RustVecRepeatExpression(new RustIntegerLiteral(0, Optional.of(RustIdentifier.of("u8"))), lengthUsize)
+ ),
+ new RustExpressionStatement(new RustTryPropagationExpression(new RustCallExpression(
+ new RustFieldExpression(
+ RustPath.of(READER_NAME),
+ RustIdentifier.of("read_exact")
+ ),
+ List.of(
+ new RustPrefixExpression(
+ RustPrefixOperator.BORROW_MUTABLE,
+ RustPath.of(bytes)
+ )
+ )
+ )))
+ ),
+ Optional.of(RustPath.of(bytes))
+ );
+ }
+
private RustExpression generateTodo() {
return new RustCallExpression(
RustPath.of("todo!"),
@@ -508,4 +599,18 @@ public class RustTransient0Generator implements Generator {
private RustIdentifier decodeMethodName(Type type) {
return this.rustGenerator.generateFieldName("decode" + type.name());
}
+
+ private RustExpression methodCall(
+ RustExpression receiver,
+ RustIdentifier methodName,
+ List<RustExpression> args
+ ) {
+ return new RustCallExpression(
+ new RustFieldExpression(
+ receiver,
+ methodName
+ ),
+ args
+ );
+ }
}