]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
json: make it easy to dispatch our enums 33425/head
authorLennart Poettering <lennart@poettering.net>
Thu, 20 Jun 2024 07:39:51 +0000 (09:39 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 20 Jun 2024 16:25:11 +0000 (18:25 +0200)
This does the opposite of the previous patch: it undoes the "-" → "_"
mapping of enum values when we try to parse enums again.

src/libsystemd/sd-json/json-util.h
src/test/test-json.c

index 2b5ef521b6bd384ce6a333769eb1ccc2e72b2d10..72c8d80bf7df7de3f19fff2e7a18d99ea3bcab49 100644 (file)
@@ -60,8 +60,16 @@ struct json_variant_foreach_state {
                         return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(n)); \
                                                                         \
                 type cc = func(sd_json_variant_string(variant));        \
-                if (cc < 0)                                             \
-                        return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "Value of JSON field '%s' not recognized.", strna(n)); \
+                if (cc < 0) {                                           \
+                        /* Maybe this enum is recognizable if we replace "_" (i.e. Varlink syntax) with "-" (how we usually prefer it). */ \
+                        _cleanup_free_ char *z = strreplace(sd_json_variant_string(variant), "_", "-"); \
+                        if (!z)                                         \
+                                return json_log_oom(variant, flags);    \
+                                                                        \
+                        cc = func(z);                                   \
+                        if (cc < 0)                                     \
+                                return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "Value of JSON field '%s' not recognized: %s", strna(n), sd_json_variant_string(variant)); \
+                }                                                       \
                                                                         \
                 *c = cc;                                                \
                 return 0;                                               \
index 5ebb5dd4a0cdeae2b96e8600beb3d351f5944d06..aea4bbaf3efb84cbdaa5963916d3413aa6a4467f 100644 (file)
@@ -917,37 +917,40 @@ TEST(json_dispatch) {
 }
 
 typedef enum mytestenum {
-        myfoo, mybar, mybaz, _mymax, _myinvalid = -EINVAL,
+        myfoo, mybar, mybaz, with_some_dashes, _mymax, _myinvalid = -EINVAL,
 } mytestenum;
 
 static const char *mytestenum_table[_mymax] = {
         [myfoo] = "myfoo",
         [mybar] = "mybar",
         [mybaz] = "mybaz",
+        [with_some_dashes] = "with-some-dashes",
 };
 
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(mytestenum, mytestenum);
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP(mytestenum, mytestenum);
 
 static JSON_DISPATCH_ENUM_DEFINE(dispatch_mytestenum, mytestenum, mytestenum_from_string);
 
 TEST(json_dispatch_enum_define) {
 
         struct data {
-                mytestenum a, b, c, d;
+                mytestenum a, b, c, d, e;
         } data = {
                 .a = _myinvalid,
                 .b = _myinvalid,
                 .c = _myinvalid,
                 .d = mybar,
+                .e = _myinvalid,
         };
 
         _cleanup_(sd_json_variant_unrefp) sd_json_variant *j = NULL;
 
-        assert_se(sd_json_build(&j, SD_JSON_BUILD_OBJECT(
-                                             SD_JSON_BUILD_PAIR("a", SD_JSON_BUILD_STRING("mybaz")),
-                                             SD_JSON_BUILD_PAIR("b", SD_JSON_BUILD_STRING("mybar")),
-                                             SD_JSON_BUILD_PAIR("c", SD_JSON_BUILD_STRING("myfoo")),
-                                             SD_JSON_BUILD_PAIR("d", SD_JSON_BUILD_NULL))) >= 0);
+        assert_se(sd_json_buildo(&j,
+                                 SD_JSON_BUILD_PAIR("a", SD_JSON_BUILD_STRING("mybaz")),
+                                 SD_JSON_BUILD_PAIR("b", SD_JSON_BUILD_STRING("mybar")),
+                                 SD_JSON_BUILD_PAIR("c", SD_JSON_BUILD_STRING("myfoo")),
+                                 SD_JSON_BUILD_PAIR("d", SD_JSON_BUILD_NULL),
+                                 SD_JSON_BUILD_PAIR("e", JSON_BUILD_STRING_UNDERSCORIFY(mytestenum_to_string(with_some_dashes)))) >= 0);
 
         assert_se(sd_json_dispatch(j,
                                 (const sd_json_dispatch_field[]) {
@@ -955,6 +958,7 @@ TEST(json_dispatch_enum_define) {
                                         { "b", _SD_JSON_VARIANT_TYPE_INVALID, dispatch_mytestenum, offsetof(struct data, b), 0 },
                                         { "c", _SD_JSON_VARIANT_TYPE_INVALID, dispatch_mytestenum, offsetof(struct data, c), 0 },
                                         { "d", _SD_JSON_VARIANT_TYPE_INVALID, dispatch_mytestenum, offsetof(struct data, d), 0 },
+                                        { "e", _SD_JSON_VARIANT_TYPE_INVALID, dispatch_mytestenum, offsetof(struct data, e), 0 },
                                         {},
                                 },
                                 /* flags= */ 0,
@@ -964,6 +968,7 @@ TEST(json_dispatch_enum_define) {
         assert(data.b == mybar);
         assert(data.c == myfoo);
         assert(data.d < 0);
+        assert(data.e == with_some_dashes);
 }
 
 TEST(json_dispatch_double) {