aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-02-07 13:57:20 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2024-02-07 15:02:57 +0200
commit0249399f06ab77c58e02698a6a0b2352f0dbf1ae (patch)
tree2d64b29d85ccb935e8ca989c17bd939326e13f72
parent82fca76bdd4183593702d80c5c41520e8b9d9ad0 (diff)
Add $json.object_names() function
-rw-r--r--libbuild2/functions-json.cxx76
-rw-r--r--tests/function/json/testscript52
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