json: make it easy to dispatch our enums

This does the opposite of the previous patch: it undoes the "-" → "_"
mapping of enum values when we try to parse enums again.
This commit is contained in:
Lennart Poettering 2024-06-20 09:39:51 +02:00
parent a556a71e9c
commit 45840c2297
2 changed files with 23 additions and 10 deletions

View 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; \

View 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) {