From 0249399f06ab77c58e02698a6a0b2352f0dbf1ae Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 7 Feb 2024 13:57:20 +0200 Subject: Add $json.object_names() function --- libbuild2/functions-json.cxx | 76 +++++++++++++++++++++++++++--------------- 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() + // $value_size() + // + // 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::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() // // 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() + // $member_value() // // 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() + // $object_names() // - // 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::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() 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 +: +$* <>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 : $* <>EOO @@ -55,24 +80,19 @@ two 2 three 3 EOO -: size +: names : $* <>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 -- cgit v1.1