forked from weaselab/weaseljson
Merge pull request 'schemagen: keep null elements in arrays with nullable item types' (#8) from weaselbot/weaseljson:weaselbot/issue-5 into main
Reviewed-on: weaselab/weaseljson#8
This commit is contained in:
@@ -71,6 +71,24 @@
|
|||||||
},
|
},
|
||||||
"tree": {
|
"tree": {
|
||||||
"$ref": "#/$defs/Node"
|
"$ref": "#/$defs/Node"
|
||||||
|
},
|
||||||
|
"nullable_hobbies": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nullable_scores": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": [
|
||||||
|
"integer",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"$defs": {
|
"$defs": {
|
||||||
|
|||||||
@@ -86,7 +86,9 @@ int main() {
|
|||||||
"value": 1,
|
"value": 1,
|
||||||
"children": [ { "value": 2 }, { "value": 3 } ],
|
"children": [ { "value": 2 }, { "value": 3 } ],
|
||||||
"next": { "value": 99 }
|
"next": { "value": 99 }
|
||||||
}
|
},
|
||||||
|
"nullable_hobbies": [null, "math", null, "lace", null],
|
||||||
|
"nullable_scores": [null, 10, null, 20, null]
|
||||||
})";
|
})";
|
||||||
RootBuilder b;
|
RootBuilder b;
|
||||||
WeaselJsonStatus s = parseStrided(b, json);
|
WeaselJsonStatus s = parseStrided(b, json);
|
||||||
@@ -116,6 +118,16 @@ int main() {
|
|||||||
CHECK(r.tree && r.tree->children && (*r.tree->children)[0].value == 2);
|
CHECK(r.tree && r.tree->children && (*r.tree->children)[0].value == 2);
|
||||||
CHECK(r.tree && r.tree->children && (*r.tree->children)[1].value == 3);
|
CHECK(r.tree && r.tree->children && (*r.tree->children)[1].value == 3);
|
||||||
CHECK(r.tree && r.tree->next && r.tree->next->value == 99);
|
CHECK(r.tree && r.tree->next && r.tree->next->value == 99);
|
||||||
|
CHECK(r.nullable_hobbies.has_value() && r.nullable_hobbies->size() == 5);
|
||||||
|
CHECK(r.nullable_hobbies && !(*r.nullable_hobbies)[0] &&
|
||||||
|
(*r.nullable_hobbies)[1] && *(*r.nullable_hobbies)[1] == "math" &&
|
||||||
|
!(*r.nullable_hobbies)[2] && (*r.nullable_hobbies)[3] &&
|
||||||
|
*(*r.nullable_hobbies)[3] == "lace" && !(*r.nullable_hobbies)[4]);
|
||||||
|
CHECK(r.nullable_scores.has_value() && r.nullable_scores->size() == 5);
|
||||||
|
CHECK(r.nullable_scores && !(*r.nullable_scores)[0] &&
|
||||||
|
(*r.nullable_scores)[1] && *(*r.nullable_scores)[1] == 10 &&
|
||||||
|
!(*r.nullable_scores)[2] && (*r.nullable_scores)[3] &&
|
||||||
|
*(*r.nullable_scores)[3] == 20 && !(*r.nullable_scores)[4]);
|
||||||
printf("ok happy path (byte-strided)\n");
|
printf("ok happy path (byte-strided)\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -718,6 +718,34 @@ namespace {ns} {{"""
|
|||||||
" }"
|
" }"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _is_array_kind(self):
|
||||||
|
arrs = [n for n, _ in self.arr_types]
|
||||||
|
if not arrs:
|
||||||
|
return " bool isArrayKind(Kind) const { return false; }"
|
||||||
|
cases = " ".join(f"case Kind::{n}:" for n in arrs)
|
||||||
|
return (
|
||||||
|
" bool isArrayKind(Kind k) const {\n"
|
||||||
|
f" switch (k) {{ {cases} return true; default: return false; }}\n"
|
||||||
|
" }"
|
||||||
|
)
|
||||||
|
|
||||||
|
def _append_null(self):
|
||||||
|
lines = [
|
||||||
|
" void appendNull(Frame &f) {",
|
||||||
|
" switch (f.kind) {",
|
||||||
|
]
|
||||||
|
for name, tarr in self.arr_types:
|
||||||
|
vectype = self.base_cpp(tarr)
|
||||||
|
lines.append(f" case Kind::{name}: {{")
|
||||||
|
lines.append(f" auto *v = ({vectype} *)f.dest;")
|
||||||
|
lines.append(" v->emplace_back();")
|
||||||
|
lines.append(" return;")
|
||||||
|
lines.append(" }")
|
||||||
|
lines.append(" default: return;")
|
||||||
|
lines.append(" }")
|
||||||
|
lines.append(" }")
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
def _is_strict(self):
|
def _is_strict(self):
|
||||||
strict = [n for n, o in self.b.objects.items() if o.strict]
|
strict = [n for n, o in self.b.objects.items() if o.strict]
|
||||||
if not strict:
|
if not strict:
|
||||||
@@ -992,6 +1020,10 @@ private:
|
|||||||
valueComplete();
|
valueComplete();
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
{self._is_array_kind()}
|
||||||
|
|
||||||
|
{self._append_null()}
|
||||||
|
|
||||||
void cbNull() {{
|
void cbNull() {{
|
||||||
if (error_) return;
|
if (error_) return;
|
||||||
Frame &f = stack_.back();
|
Frame &f = stack_.back();
|
||||||
@@ -999,6 +1031,7 @@ private:
|
|||||||
SlotInfo si = slotInfoG(f);
|
SlotInfo si = slotInfoG(f);
|
||||||
if (si.cat == Cat::Skip) {{ valueComplete(); return; }}
|
if (si.cat == Cat::Skip) {{ valueComplete(); return; }}
|
||||||
if (!si.nullable) {{ reject(); return; }}
|
if (!si.nullable) {{ reject(); return; }}
|
||||||
|
if (isArrayKind(f.kind)) appendNull(f); // keep null array elements
|
||||||
valueComplete(); // leave optional empty / pointer null
|
valueComplete(); // leave optional empty / pointer null
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user