diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2024-02-07 13:57:20 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2024-02-07 15:02:57 +0200 |
commit | 0249399f06ab77c58e02698a6a0b2352f0dbf1ae (patch) | |
tree | 2d64b29d85ccb935e8ca989c17bd939326e13f72 | |
parent | 82fca76bdd4183593702d80c5c41520e8b9d9ad0 (diff) |
Add $json.object_names() function
-rw-r--r-- | libbuild2/functions-json.cxx | 76 | ||||
-rw-r--r-- | tests/function/json/testscript | 52 |
2 files changed, 87 insertions, 41 deletions
diff --git a/libbuild2/functions-json.cxx b/libbuild2/functions-json.cxx index ae5bd77..5715e13 100644 --- a/libbuild2/functions-json.cxx +++ b/libbuild2/functions-json.cxx @@ -45,7 +45,39 @@ namespace build2 return to_string (v.type, dn); }; - // $member_name(<json>) + // $value_size(<json>) + // + // Return the size of a JSON value. + // + // The size of a `null` value is `0`. The sizes of simple values + // (`boolean`, `number`, and `string`) is `1`. The size of `array` and + // `object` values is the number of elements and members, respectively. + // + // Note that the size of a `string` JSON value is not the length of the + // string. To get the length call `$string.size()` instead by casting the + // JSON value to the `string` value type. + // + f["value_size"] += [] (json_value v) -> size_t + { + // Note: should be consistent with value_traits<json_value>::empty(), + // json_subscript(). + // + switch (v.type) + { + case json_type::null: return 0; + case json_type::boolean: + case json_type::signed_number: + case json_type::unsigned_number: + case json_type::hexadecimal_number: + case json_type::string: break; + case json_type::array: return v.array.size (); + case json_type::object: return v.object.size (); + } + + return 1; + }; + + // $member_name(<json-member>) // // Return the name of a JSON object member. // @@ -60,7 +92,7 @@ namespace build2 fail << "json object member expected instead of " << v.type << endf; }; - // $member_value(<json>) + // $member_value(<json-member>) // // Return the value of a JSON object member. // @@ -97,36 +129,28 @@ namespace build2 fail << "json object member expected instead of " << v.type << endf; }; - // $value_size(<json>) + // $object_names(<json-object>) // - // Return the size of a JSON value. + // Return the list of names in the JSON object. If the JSON `null` is + // passed instead, assume it is a missing object and return an empty list. // - // The size of a `null` value is `0`. The sizes of simple values - // (`boolean`, `number`, and `string`) is `1`. The size of `array` and - // `object` values is the number of elements and members, respectively. - // - // Note that the size of a `string` JSON value is not the length of the - // string. To get the length call `$string.size()` instead by casting the - // JSON value to the `string` value type. - // - f["value_size"] += [] (json_value v) -> size_t + f["object_names"] += [] (json_value o) { - // Note: should be consistent with value_traits<json_value>::empty(), - // json_subscript(). - // - switch (v.type) + names ns; + + if (o.type == json_type::null) + ; + else if (o.type == json_type::object) { - case json_type::null: return 0; - case json_type::boolean: - case json_type::signed_number: - case json_type::unsigned_number: - case json_type::hexadecimal_number: - case json_type::string: break; - case json_type::array: return v.array.size (); - case json_type::object: return v.object.size (); + ns.reserve (o.object.size ()); + + for (json_member& m: o.object) + ns.push_back (name (move (m.name))); } + else + fail << "expected json object instead of " << to_string (o.type); - return 1; + return ns; }; // $array_size(<json-array>) diff --git a/tests/function/json/testscript b/tests/function/json/testscript index 9f8c2e9..b7134a8 100644 --- a/tests/function/json/testscript +++ b/tests/function/json/testscript @@ -37,6 +37,31 @@ object object EOO +: size +: +$* <<EOI >>EOO +print $value_size([json] null) +print $value_size([json] true) +print $value_size([json] 123) +print $value_size([json] abc) +print $size([string] ([json] abc)) # @@ Should be 3 (quoted, type hint). +print $value_size([json] 1 2 3) +print $value_size([json] one@1 two@2 three@3) + +print $array_size([json] 1 2 3) +print $array_size([json] null) +EOI +0 +1 +1 +1 +5 +3 +3 +3 +0 +EOO + : member : $* <<EOI >>EOO @@ -55,24 +80,19 @@ two 2 three 3 EOO -: size +: names : $* <<EOI >>EOO -print $value_size([json] null) -print $value_size([json] true) -print $value_size([json] 123) -print $value_size([json] abc) -print $size([string] ([json] abc)) # @@ Should be 3 (quoted, type hint). -print $value_size([json] 1 2 3) -print $value_size([json] one@1 two@2 three@3) +j = [json] one@1 two@2 three@3 +for n: $object_names($j) + print $n ($j[$n]) + +print $object_names([json] null) EOI -0 -1 -1 -1 -5 -3 -3 +one 1 +two 2 +three 3 + EOO : find @@ -92,6 +112,7 @@ print $array_find_index($j, [json] one@1) print $array_find_index($j, [json] one@1 two@2 three@3) print $array_find_index($j, [json] one@1 TWO@3) print $array_find_index($j, [json] one@1 two@3) +print $array_find_index([json] null, 1) EOI 5 3 @@ -106,6 +127,7 @@ EOI 11 11 11 +0 EOO : parse |