From 2269a611da40bd7242dbd1a3204c212ac6091fd7 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 6 Feb 2024 05:22:12 +0200 Subject: Add experimental support for JSON value types --- libbuild2/variable.hxx | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'libbuild2/variable.hxx') diff --git a/libbuild2/variable.hxx b/libbuild2/variable.hxx index 9d7b001..6b0b30e 100644 --- a/libbuild2/variable.hxx +++ b/libbuild2/variable.hxx @@ -15,6 +15,8 @@ #include #include +#include + #include #include #include @@ -1201,6 +1203,65 @@ namespace build2 static const map_value_type value_type; }; + // json + // + // Note that we do not expose json_member as a value type instead + // representing it as an object with one member. While we could expose + // member (and reverse it as a pair since there is no valid JSON + // representation for a standalone member), this doesn't seem to buy us much + // but will cause complications (for example, in supporting append/prepend). + // On the other hand, representing a member as an object only requires a bit + // of what looks like harmless looseness in a few contexts (such as the + // $json.member_*() functions). + // + template <> + struct LIBBUILD2_SYMEXPORT value_traits + { + static_assert (sizeof (json_value) <= value::size_, "insufficient space"); + + static json_value convert (names&&); + static void assign (value&, json_value&&); + static void append (value&, json_value&&); + static void prepend (value&, json_value&&); + static bool empty (const json_value&); // null or empty array/object + + static const json_value empty_instance; // null + static const char* const type_name; + static const build2::value_type value_type; + }; + + template <> + struct LIBBUILD2_SYMEXPORT value_traits + { + static_assert (sizeof (json_array) <= value::size_, "insufficient space"); + + static json_array convert (names&&); + static void assign (value&, json_array&&); + static void append (value&, json_value&&); // Note: value, not array. + static void prepend (value&, json_value&&); + static bool empty (const json_array& v) {return v.array.empty ();} + + static const json_array empty_instance; // empty array + static const char* const type_name; + static const build2::value_type value_type; + }; + + template <> + struct LIBBUILD2_SYMEXPORT value_traits + { + static_assert (sizeof (json_object) <= value::size_, "insufficient space"); + + static json_object convert (names&&); + static void assign (value&, json_object&&); + static void append (value&, json_value&&); // Note: value, not object. + static void prepend (value&, json_value&&); + static bool empty (const json_object& v) {return v.object.empty ();} + + static const json_object empty_instance; // empty object + static const char* const type_name; + static const build2::value_type value_type; + }; + // Canned command line to be re-lexed (used in {Build,Test}scripts). // // Note that because the executable can be specific as a target or as -- cgit v1.1