Skip to content

Commit

Permalink
Fix regression with parsing of scalar value documents (#90)
Browse files Browse the repository at this point in the history
* Add tests for scalar value jsons

* Fix parsing of scalar value documents

With the ondemand parser, the document to value conversion fails with
the error SCALAR_DOCUMENT_AS_VALUE if the document is a single null,
string, bool, or number value.

* Add explicit types in for loop variables

Since we are now using a template type, this is no longer inferable by
an IDE. Adding explicit types also reduces the number of `.value()`
conversions required.
  • Loading branch information
tobil4sk authored Sep 16, 2024
1 parent f7b3a76 commit 789d08a
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 13 deletions.
1 change: 1 addition & 0 deletions jsonexamples/scalars/bool.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
true
1 change: 1 addition & 0 deletions jsonexamples/scalars/null.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
null
1 change: 1 addition & 0 deletions jsonexamples/scalars/number.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10
1 change: 1 addition & 0 deletions jsonexamples/scalars/string.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"hello world"
6 changes: 5 additions & 1 deletion spec/compile_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ local files = {
"repeat.json",
"twitter_timeline.json",
"update-center.json",
"scalars/bool.json",
"scalars/null.json",
"scalars/number.json",
"scalars/string.json",
"small/adversarial.json",
"small/demo.json",
"small/flatadversarial.json",
Expand Down Expand Up @@ -100,4 +104,4 @@ if tonumber(major) >= 5 and tonumber(minor) >= 3 then

end)
end)
end
end
21 changes: 9 additions & 12 deletions src/luasimdjson.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,20 @@ static void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
ondemand::parser ondemand_parser;
simdjson::padded_string jsonbuffer;

void convert_ondemand_element_to_table(lua_State *L, ondemand::value element) {
template<typename T>
void convert_ondemand_element_to_table(lua_State *L, T element) {
static_assert(std::is_base_of<ondemand::document_reference, T>::value || std::is_base_of<ondemand::value, T>::value, "type parameter must be document_reference or value");

switch (element.type()) {

case ondemand::json_type::array:
{
int count = 1;
lua_newtable(L);

for (auto child : element.get_array()) {
for (ondemand::value child : element.get_array()) {
lua_pushinteger(L, count);
// We need the call to value() to get
// an ondemand::value type.
convert_ondemand_element_to_table(L, child.value());
convert_ondemand_element_to_table(L, child);
lua_settable(L, -3);
count = count + 1;
}
Expand All @@ -63,7 +64,7 @@ void convert_ondemand_element_to_table(lua_State *L, ondemand::value element) {

case ondemand::json_type::object:
lua_newtable(L);
for (auto field : element.get_object()) {
for (ondemand::field field : element.get_object()) {
std::string_view s = field.unescaped_key();
lua_pushlstring(L, s.data(), s.size());
convert_ondemand_element_to_table(L, field.value());
Expand Down Expand Up @@ -163,13 +164,11 @@ static int parse(lua_State *L)
const char *json_str = luaL_checklstring(L, 1, &json_str_len);

ondemand::document doc;
ondemand::value element;

try {
// makes a padded_string_view for a bit of quickness!
doc = ondemand_parser.iterate(get_padded_string_view(json_str, json_str_len, jsonbuffer));
element = doc;
convert_ondemand_element_to_table(L, element);
convert_ondemand_element_to_table(L, ondemand::document_reference(doc));
} catch (simdjson::simdjson_error &error) {
luaL_error(L, error.what());
}
Expand All @@ -183,13 +182,11 @@ static int parse_file(lua_State *L)

padded_string json_string;
ondemand::document doc;
ondemand::value element;

try {
json_string = padded_string::load(json_file);
doc = ondemand_parser.iterate(json_string);
element = doc;
convert_ondemand_element_to_table(L, element);
convert_ondemand_element_to_table(L, ondemand::document_reference(doc));
} catch (simdjson::simdjson_error &error) {
luaL_error(L, error.what());
}
Expand Down

0 comments on commit 789d08a

Please sign in to comment.