diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2024-01-23 09:22:36 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2024-01-23 09:22:36 +0200 |
commit | 19b1f25a1209c7af9e73c0e68ba33574a3b4cbb7 (patch) | |
tree | 37705ff14d47e08d21f8d16fa8b572e312b19bda /libbuild2/variable.cxx | |
parent | 7d5c863e01b4a70d5ef3614b91694cf080a420c9 (diff) |
Add reversejson-type
Diffstat (limited to 'libbuild2/variable.cxx')
-rw-r--r-- | libbuild2/variable.cxx | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/libbuild2/variable.cxx b/libbuild2/variable.cxx index c83d55e..efc1eb2 100644 --- a/libbuild2/variable.cxx +++ b/libbuild2/variable.cxx @@ -1743,9 +1743,81 @@ namespace build2 */ static names_view - json_reverse (const value&, names& storage, bool) + json_reverse (const value& x, names& ns, bool) { - return names_view (storage); // @@ TODO + const json_value& v (x.as<json_value> ()); + + switch (v.type) + { + case json_type::null: + { + // @@ Hm, it would be nice if this somehow got mapped to [null]/empty + // but still be round-trippable to JSON null. Perhaps via type + // hint? + // + ns.push_back (name ("null")); + break; + } + case json_type::boolean: + { + ns.push_back (name (v.boolean ? "true" : "false")); + break; + } + case json_type::signed_number: + { + ns.push_back (value_traits<int64_t>::reverse (v.signed_number)); + break; + } + case json_type::unsigned_number: + { + ns.push_back (value_traits<uint64_t>::reverse (v.unsigned_number)); + break; + } + case json_type::string: + // @@ Hm, it would be nice if this somehow got mapped to unquoted + // string but still be round-trippable to JSON null. Perhaps via + // type hint? + // + // @@ If not, optimize for case where no escaping/quoting required? + // + case json_type::array: + case json_type::object: + { + // Serialize as JSON output. + // + string o; + +#ifndef BUILD2_BOOTSTRAP + using namespace butl::json; + + try + { + // Disable pretty-printing so that the output is all on the same + // line. While it's not going to be easy to read for larger JSON + // outputs, it will fit better into the existing model where none of + // the value representations use formatting newlines. If a pretty- + // printed representation is required, then the @@ function can be + // used to obtain it. + // + buffer_serializer s (o, 0 /* indentation */); + serialize (s, v); + } + catch (const invalid_json_output& e) + { + // @@ How can we communicate event, offset? But for that to be + // useful we would also need to somehow also dump the value. + // + fail << "invalid json value: " << e; + } +#else + fail << "json serialization requested during bootstrap"; +#endif + ns.push_back (name (move (o))); + break; + } + } + + return ns; } static int |