Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issues/256 - Nested option with map deserialization fix. #257

Merged
merged 2 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.casper.sdk.model.clvalue;

import com.casper.sdk.annotation.ExcludeFromJacocoGeneratedReport;
import com.casper.sdk.model.clvalue.cltype.AbstractCLType;
import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren;
import com.casper.sdk.model.clvalue.cltype.CLTypeByteArray;
import com.fasterxml.jackson.annotation.JsonSetter;
import dev.oak3.sbs4j.DeserializerBuffer;
import dev.oak3.sbs4j.exception.ValueDeserializationException;
Expand Down Expand Up @@ -33,6 +35,16 @@ protected void childTypesSet() {
}
}

protected void populateChildTypesFromParent(final AbstractCLValue<?, ?> child, final AbstractCLType type) {
if (type instanceof AbstractCLTypeWithChildren) {
if (child.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child.getClType()).setChildTypes(((AbstractCLTypeWithChildren)type).getChildTypes());
} else if (child instanceof CLValueByteArray) {
((CLValueByteArray) child).setClType((CLTypeByteArray) ((AbstractCLTypeWithChildren)type).getChildTypes().get(0));
}
}
}

/**
* Sets the bytes and if the CLType is already set, fires bytes deserialization
*
Expand Down
10 changes: 1 addition & 9 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueList.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.casper.sdk.model.clvalue;

import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren;
import com.casper.sdk.model.clvalue.cltype.CLTypeData;
import com.casper.sdk.model.clvalue.cltype.CLTypeList;
import com.casper.sdk.model.clvalue.cltype.CLTypeMap;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import dev.oak3.sbs4j.DeserializerBuffer;
Expand Down Expand Up @@ -78,13 +76,7 @@ public void deserializeCustom(final DeserializerBuffer deser) throws Exception {
final List<AbstractCLValue<?, ?>> list = new ArrayList<>();
for (int i = 0; i < length.getValue(); i++) {
final AbstractCLValue<?, ?> child = CLTypeData.createCLValueFromCLTypeData(childrenType);
if (child.getClType() instanceof CLTypeMap) {
((CLTypeMap) child.getClType())
.setKeyValueTypes(((CLTypeMap) clType.getListType()).getKeyValueTypes());
} else if (child.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getListType()).getChildTypes());
}
populateChildTypesFromParent(child, clType.getListType());
child.deserializeCustom(deser);
list.add(child);
}
Expand Down
18 changes: 3 additions & 15 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.casper.sdk.model.clvalue;

import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren;
import com.casper.sdk.model.clvalue.cltype.CLTypeData;
import com.casper.sdk.model.clvalue.cltype.CLTypeMap;
import com.fasterxml.jackson.annotation.JsonIgnore;
Expand Down Expand Up @@ -85,23 +84,12 @@ public void deserializeCustom(final DeserializerBuffer deser) throws Exception {

for (int i = 0; i < mapLength.getValue(); i++) {
final AbstractCLValue<?, ?> key = CLTypeData.createCLValueFromCLTypeData(keyType);
if (key.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) key.getClType())
.setChildTypes(
((AbstractCLTypeWithChildren) clType.getKeyValueTypes().getKeyType()).getChildTypes());
}
// It's very unlikely we have a key that is complex type but adding support
populateChildTypesFromParent(key, clType.getKeyValueTypes().getKeyType());
key.deserializeCustom(deser);

final AbstractCLValue<?, ?> val = CLTypeData.createCLValueFromCLTypeData(valType);

if (val.getClType() instanceof CLTypeMap) {
((CLTypeMap) val.getClType())
.setKeyValueTypes(((CLTypeMap) clType.getKeyValueTypes().getValueType()).getKeyValueTypes());
} else if (val.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) val.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getKeyValueTypes().getValueType())
.getChildTypes());
}
populateChildTypesFromParent(val, clType.getKeyValueTypes().getValueType());
val.deserializeCustom(deser);

map.put(key, val);
Expand Down
17 changes: 4 additions & 13 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueOption.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.casper.sdk.model.clvalue;

import com.casper.sdk.model.clvalue.cltype.*;
import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren;
import com.casper.sdk.model.clvalue.cltype.CLTypeData;
import com.casper.sdk.model.clvalue.cltype.CLTypeOption;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import dev.oak3.sbs4j.DeserializerBuffer;
Expand Down Expand Up @@ -70,19 +72,8 @@ public void deserializeCustom(final DeserializerBuffer deser) throws Exception {
isPresent.deserializeCustom(deser);

final CLTypeData childTypeData = clType.getOptionType().getClTypeData();

final AbstractCLValue<?, ?> child = CLTypeData.createCLValueFromCLTypeData(childTypeData);

if (child.getClType() instanceof CLTypeList) {
((CLTypeList) child.getClType())
.setListType(((CLTypeList) clType.getOptionType()).getListType());
} else if (child.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getOptionType()).getChildTypes());
} else if (child instanceof CLValueByteArray) {
// Byte arrays require their length to be set to correctly deserialize
((CLValueByteArray) child).setClType((CLTypeByteArray) clType.getOptionType());
}
populateChildTypesFromParent(child, clType.getOptionType());

if (Boolean.TRUE.equals(isPresent.getValue())) {
child.deserializeCustom(deser);
Expand Down
10 changes: 3 additions & 7 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueTuple1.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.casper.sdk.model.clvalue;

import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren;
import com.casper.sdk.model.clvalue.cltype.CLTypeData;
import com.casper.sdk.model.clvalue.cltype.CLTypeTuple1;
import com.fasterxml.jackson.annotation.JsonProperty;
Expand Down Expand Up @@ -57,13 +56,10 @@ protected void serializeValue(final SerializerBuffer ser) throws ValueSerializat

@Override
public void deserializeCustom(final DeserializerBuffer deser) throws Exception {
CLTypeData childTypeData1 = clType.getChildClTypeData(0);
final CLTypeData childTypeData1 = clType.getChildClTypeData(0);

AbstractCLValue<?, ?> child1 = CLTypeData.createCLValueFromCLTypeData(childTypeData1);
if (child1.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child1.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getChildTypes().get(0)).getChildTypes());
}
final AbstractCLValue<?, ?> child1 = CLTypeData.createCLValueFromCLTypeData(childTypeData1);
populateChildTypesFromParent(child1, clType.getChildTypes().get(0));
child1.deserializeCustom(deser);

setValue(new Unit<>(child1));
Expand Down
11 changes: 2 additions & 9 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueTuple2.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.casper.sdk.model.clvalue;

import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren;
import com.casper.sdk.model.clvalue.cltype.CLTypeData;
import com.casper.sdk.model.clvalue.cltype.CLTypeTuple2;
import com.fasterxml.jackson.annotation.JsonProperty;
Expand Down Expand Up @@ -64,17 +63,11 @@ public void deserializeCustom(final DeserializerBuffer deser) throws Exception {
final CLTypeData childTypeData2 = clType.getChildClTypeData(1);

final AbstractCLValue<?, ?> child1 = CLTypeData.createCLValueFromCLTypeData(childTypeData1);
if (child1.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child1.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getChildTypes().get(0)).getChildTypes());
}
populateChildTypesFromParent(child1, clType.getChildTypes().get(0));
child1.deserializeCustom(deser);

final AbstractCLValue<?, ?> child2 = CLTypeData.createCLValueFromCLTypeData(childTypeData2);
if (child2.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child2.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getChildTypes().get(1)).getChildTypes());
}
populateChildTypesFromParent(child2, clType.getChildTypes().get(1));
child2.deserializeCustom(deser);

setValue(new Pair<>(child1, child2));
Expand Down
17 changes: 4 additions & 13 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueTuple3.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.casper.sdk.model.clvalue;

import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren;
import com.casper.sdk.model.clvalue.cltype.CLTypeData;
import com.casper.sdk.model.clvalue.cltype.CLTypeTuple3;
import com.fasterxml.jackson.annotation.JsonProperty;
Expand Down Expand Up @@ -65,29 +64,21 @@ public void deserializeCustom(final DeserializerBuffer deser) throws Exception {
final CLTypeData childTypeData3 = clType.getChildClTypeData(2);

final AbstractCLValue<?, ?> child1 = CLTypeData.createCLValueFromCLTypeData(childTypeData1);
if (child1.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child1.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getChildTypes().get(0)).getChildTypes());
}
populateChildTypesFromParent(child1, clType.getChildTypes().get(0));
child1.deserializeCustom(deser);

final AbstractCLValue<?, ?> child2 = CLTypeData.createCLValueFromCLTypeData(childTypeData2);
if (child2.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child2.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getChildTypes().get(1)).getChildTypes());
}
populateChildTypesFromParent(child2, clType.getChildTypes().get(1));
child2.deserializeCustom(deser);

final AbstractCLValue<?, ?> child3 = CLTypeData.createCLValueFromCLTypeData(childTypeData3);
if (child3.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child3.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getChildTypes().get(2)).getChildTypes());
}
populateChildTypesFromParent(child3, clType.getChildTypes().get(2));
child3.deserializeCustom(deser);

setValue(new Triplet<>(child1, child2, child3));
}


@Override
protected void setChildTypes(final Triplet<? extends AbstractCLValue<?, ?>, ? extends AbstractCLValue<?, ?>, ? extends AbstractCLValue<?, ?>> value) {
if (value.getValue0() != null && value.getValue1() != null && value.getValue2() != null) {
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import dev.oak3.sbs4j.exception.ValueDeserializationException;
import lombok.*;

import java.util.List;

/**
* CLType for {@link AbstractCLType#MAP}
*
Expand Down Expand Up @@ -53,6 +55,19 @@ public boolean isDeserializable() {
}
}

/**
* Allows generic setting of child types so we don't need specialized code for byte deserialization.
*
* @param childTypes the child types
*/
@Override
public void setChildTypes(final List<AbstractCLType> childTypes) {
super.setChildTypes(childTypes);
if (childTypes.size() >= 2) {
setKeyValueTypes(new CLTypeMapEntryType(childTypes.get(0), childTypes.get(1)));
}
}

/**
* Support class for {@link AbstractCLType#MAP} entry types
*
Expand Down
20 changes: 20 additions & 0 deletions src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -364,4 +364,24 @@ void Ed25519PublicKeySerialization() throws Exception {
assertThat(deserialized.getBytes(), is(clValuePublicKey.getBytes()));
}

@Test
void nestedOptionWithMap() throws Exception {

final Map<CLValueString, CLValueU32> map = new HashMap<>();
map.put(new CLValueString("ONE"), new CLValueU32(2L));
final CLValueMap innerMap = new CLValueMap(map);
final CLValueOption innerOption = new CLValueOption(Optional.of(innerMap));
CLValueOption clValueOption = new CLValueOption(Optional.of(innerOption));

assertThat(clValueOption.getBytes(), is("010101000000030000004f4e4502000000"));

final SerializerBuffer ser = new SerializerBuffer();
clValueOption.serialize(ser, Target.BYTE);

final byte[] bytes = ser.toByteArray();
assertThat(bytes, is(Hex.decode("11000000010101000000030000004f4e45020000000d0d110a04")));

final CLValueOption deserialized = (CLValueOption) clValueOption.deserialize(new DeserializerBuffer(bytes), Target.BYTE);
assertThat(deserialized.getBytes(), is(clValueOption.getBytes()));
}
}
Loading