aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/json.ixx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-02-06 05:22:12 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2024-02-07 15:02:38 +0200
commit36d6b4e5549dc45baf890105de5ef487211f0144 (patch)
tree762f9eba621026e9bb7d8fd69107a4447783a45a /libbuild2/json.ixx
parenta5acaba537dab8e06be1197916acff86699aa5a3 (diff)
Add experimental support for JSON value types
New types: json json_array json_object New functions: $json.value_type(<json>) $json.value_size(<json>) $json.member_{name,value}(<json-member>) $json.object_names(<json-object>) $json.array_size(<json-array>) $json.array_find(<json-array>, <json>) $json.array_find_index(<json-array>, <json>) $json.load(<path>) $json.parse(<text>) $json.serialize(<json>[, <indentation>]) For example, to load a JSON value from a file: j = $json.load($src_base/board.json) Or to construct it in a buildfile: j = [json] one@1 two@([json] 2 3 4) three@([json] x@1 y@-1) This can also be done incrementally with append/prepend: j = [json_object] j += one@1 j += two@([json] 2 3 4) j += three@([json] x@1 y@-1) Instead of using this JSON-like syntax, one can also specify valid JSON input text: j = [json] '{"one":1, "two":[2, 3, 4], "three":{"x":1, "y":-1}' Besides the above set of functions, other handy ways to access components in a JSON value are iteration and subscript. For example: for m: $j print $member_name($m) $member_value($m) print ($j[three]) A subscript can be nested: print ($j[two][1]) print ($j[three][x]) While a JSON value can be printed directly like any other value, the representation will not be pretty-printed. As a result, for complex JSON values, printing a serialized representation might be a more readable option: info $serialize($j)
Diffstat (limited to 'libbuild2/json.ixx')
-rw-r--r--libbuild2/json.ixx222
1 files changed, 222 insertions, 0 deletions
diff --git a/libbuild2/json.ixx b/libbuild2/json.ixx
new file mode 100644
index 0000000..c2b8845
--- /dev/null
+++ b/libbuild2/json.ixx
@@ -0,0 +1,222 @@
+// file : libbuild2/json.ixx -*- C++ -*-
+// license : MIT; see accompanying LICENSE file
+
+namespace build2
+{
+ inline json_value::
+ ~json_value () noexcept
+ {
+ switch (type)
+ {
+ case json_type::null:
+ case json_type::boolean:
+ case json_type::signed_number:
+ case json_type::unsigned_number:
+ case json_type::hexadecimal_number: break;
+ case json_type::string: string.~string_type (); break;
+ case json_type::array: array.~array_type (); break;
+ case json_type::object: object.~object_type (); break;
+ }
+ }
+
+ inline json_value::
+ json_value (json_type t) noexcept
+ : type (t)
+ {
+ switch (type)
+ {
+ case json_type::null: break;
+ case json_type::boolean: boolean = false; break;
+ case json_type::signed_number: signed_number = 0; break;
+ case json_type::unsigned_number:
+ case json_type::hexadecimal_number: unsigned_number = 0; break;
+ case json_type::string: new (&string) string_type (); break;
+ case json_type::array: new (&array) array_type (); break;
+ case json_type::object: new (&object) object_type (); break;
+ }
+ }
+
+ inline json_value::
+ json_value (std::nullptr_t) noexcept
+ : type (json_type::null)
+ {
+ }
+
+ inline json_value::
+ json_value (bool v) noexcept
+ : type (json_type::boolean), boolean (v)
+ {
+ }
+
+ inline json_value::
+ json_value (int64_t v) noexcept
+ : type (json_type::signed_number), signed_number (v)
+ {
+ }
+
+ inline json_value::
+ json_value (uint64_t v, bool hex) noexcept
+ : type (hex
+ ? json_type::hexadecimal_number
+ : json_type::unsigned_number),
+ unsigned_number (v)
+ {
+ }
+
+ inline json_value::
+ json_value (string_type v)
+ : type (json_type::string), string (move (v))
+ {
+ }
+
+ inline const json_value& json_value::
+ at (const string_type& n) const
+ {
+ return at (n.c_str ());
+ }
+
+ inline json_value& json_value::
+ at (const string_type& n)
+ {
+ return at (n.c_str ());
+ }
+
+ inline const json_value& json_value::
+ operator[] (const string_type& n) const
+ {
+ return operator[] (n.c_str ());
+ }
+
+ inline json_value& json_value::
+ operator[] (const string_type& n)
+ {
+ return operator[] (n.c_str ());
+ }
+
+ inline json_value::
+ json_value (json_value&& v) noexcept
+ : type (v.type)
+ {
+ switch (type)
+ {
+ case json_type::null:
+ break;
+ case json_type::boolean:
+ boolean = v.boolean;
+ break;
+ case json_type::signed_number:
+ signed_number = v.signed_number;
+ break;
+ case json_type::unsigned_number:
+ case json_type::hexadecimal_number:
+ unsigned_number = v.unsigned_number;
+ break;
+ case json_type::string:
+ new (&string) string_type (move (v.string));
+ v.string.~string_type ();
+ break;
+ case json_type::array:
+ new (&array) array_type (move (v.array));
+ v.array.~array_type ();
+ break;
+ case json_type::object:
+ new (&object) object_type (move (v.object));
+ v.object.~object_type ();
+ break;
+ }
+
+ v.type = json_type::null;
+ }
+
+ inline json_value::
+ json_value (const json_value& v)
+ : type (v.type)
+ {
+ switch (type)
+ {
+ case json_type::null:
+ break;
+ case json_type::boolean:
+ boolean = v.boolean;
+ break;
+ case json_type::signed_number:
+ signed_number = v.signed_number;
+ break;
+ case json_type::unsigned_number:
+ case json_type::hexadecimal_number:
+ unsigned_number = v.unsigned_number;
+ break;
+ case json_type::string:
+ new (&string) string_type (v.string);
+ break;
+ case json_type::array:
+ new (&array) array_type (v.array);
+ break;
+ case json_type::object:
+ new (&object) object_type (v.object);
+ break;
+ }
+ }
+
+ inline json_value& json_value::
+ operator= (json_value&& v) noexcept
+ {
+ if (this != &v)
+ {
+ this->~json_value ();
+ new (this) json_value (move (v));
+ }
+ return *this;
+ }
+
+ inline json_value& json_value::
+ operator= (const json_value& v)
+ {
+ if (this != &v)
+ {
+ this->~json_value ();
+ new (this) json_value (v);
+ }
+ return *this;
+ }
+
+ // json_array
+ //
+ inline json_array::
+ json_array () noexcept
+ : json_value (json_type::array)
+ {
+ }
+
+ inline json_array::
+ json_array (json_parser& p)
+ : json_value (p, json_type::array)
+ {
+ }
+
+ inline void json_array::
+ serialize (json_buffer_serializer& s) const
+ {
+ json_value::serialize (s, json_type::array);
+ }
+
+ // json_object
+ //
+ inline json_object::
+ json_object () noexcept
+ : json_value (json_type::object)
+ {
+ }
+
+ inline json_object::
+ json_object (json_parser& p)
+ : json_value (p, json_type::object)
+ {
+ }
+
+ inline void json_object::
+ serialize (json_buffer_serializer& s) const
+ {
+ json_value::serialize (s, json_type::object);
+ }
+}