summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java36
-rw-r--r--examples/10-transient-0/src/data.hob5
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java86
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java8
4 files changed, 135 insertions, 0 deletions
diff --git a/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java b/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java
index b7e841c..40acde4 100644
--- a/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java
+++ b/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java
@@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
+import java.util.Optional;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.zwobble.example.types.data.HobgoblinTransient0Data;
@@ -13,6 +14,7 @@ import org.zwobble.example.types.data.StructWithBool;
import org.zwobble.example.types.data.StructWithInt32;
import org.zwobble.example.types.data.StructWithInt64;
import org.zwobble.example.types.data.StructWithList;
+import org.zwobble.example.types.data.StructWithOption;
import org.zwobble.example.types.data.StructWithString;
public class Transient0Tests {
@@ -106,4 +108,38 @@ public class Transient0Tests {
Assertions.assertEquals(value, decodedValue);
}
+
+ @Test
+ public void structWithOptionNone() throws IOException {
+ var value = new StructWithOption(
+ Optional.empty(),
+ Optional.empty()
+ );
+
+ var outputStream = new ByteArrayOutputStream();
+ HobgoblinTransient0Data.encodeStructWithOption(value, outputStream);
+ var bytes = outputStream.toByteArray();
+
+ var inputStream = new ByteArrayInputStream(bytes);
+ var decodedValue = HobgoblinTransient0Data.decodeStructWithOption(inputStream);
+
+ Assertions.assertEquals(value, decodedValue);
+ }
+
+ @Test
+ public void structWithOptionSome() throws IOException {
+ var value = new StructWithOption(
+ Optional.of(10L),
+ Optional.of(new InnerStruct(42, 47))
+ );
+
+ var outputStream = new ByteArrayOutputStream();
+ HobgoblinTransient0Data.encodeStructWithOption(value, outputStream);
+ var bytes = outputStream.toByteArray();
+
+ var inputStream = new ByteArrayInputStream(bytes);
+ var decodedValue = HobgoblinTransient0Data.decodeStructWithOption(inputStream);
+
+ Assertions.assertEquals(value, decodedValue);
+ }
}
diff --git a/examples/10-transient-0/src/data.hob b/examples/10-transient-0/src/data.hob
index 8550d6d..80ba8e5 100644
--- a/examples/10-transient-0/src/data.hob
+++ b/examples/10-transient-0/src/data.hob
@@ -32,3 +32,8 @@ struct StructWithList {
field a: List[Int64];
field b: List[InnerStruct];
}
+
+struct StructWithOption {
+ field a: Option[Int64];
+ field b: Option[InnerStruct];
+}
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 5feba05..59dcefe 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
@@ -433,6 +433,8 @@ public class JavaTransient0Generator implements Generator {
case ConstructedNativeType constructedNativeType -> {
if (constructedNativeType.constructor().equals(NativeTypes.LIST)) {
yield generateEncodeList(value, constructedNativeType.args().getFirst());
+ } else if (constructedNativeType.constructor().equals(NativeTypes.OPTION)) {
+ yield generateEncodeOption(value, constructedNativeType.args().getFirst());
} else {
throw new UnsupportedOperationException("TODO");
}
@@ -491,6 +493,8 @@ public class JavaTransient0Generator implements Generator {
case ConstructedNativeType constructedNativeType -> {
if (constructedNativeType.constructor().equals(NativeTypes.LIST)) {
yield generateDecodeList(target, constructedNativeType.args().getFirst());
+ } else if (constructedNativeType.constructor().equals(NativeTypes.OPTION)) {
+ yield generateDecodeOption(target, constructedNativeType.args().getFirst());
} else {
throw new UnsupportedOperationException("TODO");
}
@@ -633,6 +637,88 @@ public class JavaTransient0Generator implements Generator {
return statements;
}
+ private List<JavaBlockStatement> generateEncodeOption(
+ JavaExpression value,
+ Type elementType
+ ) {
+ var statements = new ArrayList<JavaBlockStatement>();
+ var isPresent = new JavaMethodCall(
+ value,
+ JavaIdentifier.of("isPresent"),
+ List.of()
+ );
+
+ statements.addAll(generateEncode(
+ isPresent,
+ NativeTypes.BOOL
+ ));
+
+ statements.add(new JavaIfStatement(
+ isPresent,
+ new JavaBlock(generateEncode(
+ new JavaMethodCall(
+ value,
+ JavaIdentifier.of("get"),
+ List.of()
+ ),
+ elementType
+ )),
+ new JavaBlock(List.of())
+ ));
+
+ return statements;
+ }
+
+ private List<JavaBlockStatement> generateDecodeOption(
+ JavaIdentifier target,
+ Type elementType
+ ) {
+ var isPresent = JavaIdentifier.of(target.value() + "$isPresent");
+ var element = JavaIdentifier.of(target.value() + "$element");
+
+ var statements = new ArrayList<JavaBlockStatement>();
+
+ statements.addAll(generateDecode(isPresent, NativeTypes.BOOL));
+
+ statements.add(new JavaLocalVariableDeclaration(
+ Optional.of(JavaTypeRef.optional(this.javaGenerator.generateReferenceTypeRef(elementType))),
+ target,
+ Optional.empty()
+ ));
+
+ var ifTrue = new ArrayList<JavaBlockStatement>();
+
+ ifTrue.addAll(generateDecode(element, elementType));
+
+ ifTrue.add(new JavaExpressionStatement(new JavaBinaryOperation(
+ JavaBinaryOperator.ASSIGN,
+ new JavaRef(target),
+ new JavaStaticMethodCall(
+ JavaTypeRef.OPTIONAL,
+ JavaIdentifier.of("of"),
+ List.of(new JavaRef(element))
+ )
+ )));
+
+ statements.add(new JavaIfStatement(
+ new JavaRef(isPresent),
+ new JavaBlock(ifTrue),
+ new JavaBlock(List.of(
+ new JavaExpressionStatement(new JavaBinaryOperation(
+ JavaBinaryOperator.ASSIGN,
+ new JavaRef(target),
+ new JavaStaticMethodCall(
+ JavaTypeRef.OPTIONAL,
+ JavaIdentifier.of("empty"),
+ List.of()
+ )
+ ))
+ ))
+ ));
+
+ return statements;
+ }
+
private static JavaMethodCall generateOutputStreamWrite(JavaExpression byteToWrite) {
return new JavaMethodCall(
new JavaRef(OUTPUT_STREAM_NAME),
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java
index 0975e4e..8dbca61 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java
@@ -75,6 +75,14 @@ public record JavaTypeRef(JavaPackageName packageName, List<JavaIdentifier> type
public static final JavaTypeRef OPTIONAL = topLevel(JavaPackages.JAVA_UTIL, JavaIdentifier.of("Optional"));
+ public static JavaTypeRef optional(JavaTypeRef elementType) {
+ return new JavaTypeRef(
+ OPTIONAL.packageName,
+ OPTIONAL.typeNames,
+ List.of(JavaTypeArg.invariant(elementType))
+ );
+ }
+
public static final JavaTypeRef OUTPUT_STREAM = topLevel(JavaPackages.JAVA_IO, JavaIdentifier.of("OutputStream"));
public static final JavaTypeRef STANDARD_CHARSETS = topLevel(JavaPackages.JAVA_NIO_CHARSET, JavaIdentifier.of("StandardCharsets"));