mirror of
https://github.com/systemd/systemd.git
synced 2025-01-09 01:18:19 +03:00
Merge pull request #33425 from poettering/json-enum-easier
json: make serializing/deserializing systemd-style enums easier in Varlink
This commit is contained in:
commit
5b272499dc
@ -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; \
|
||||
@ -130,6 +138,7 @@ enum {
|
||||
_JSON_BUILD_IOVEC_HEX,
|
||||
_JSON_BUILD_HW_ADDR,
|
||||
_JSON_BUILD_STRING_SET,
|
||||
_JSON_BUILD_STRING_UNDERSCORIFY,
|
||||
|
||||
_JSON_BUILD_PAIR_UNSIGNED_NON_ZERO,
|
||||
_JSON_BUILD_PAIR_FINITE_USEC,
|
||||
@ -156,6 +165,7 @@ enum {
|
||||
#define JSON_BUILD_ETHER_ADDR(v) SD_JSON_BUILD_BYTE_ARRAY(((const struct ether_addr*) { v })->ether_addr_octet, sizeof(struct ether_addr))
|
||||
#define JSON_BUILD_HW_ADDR(v) _JSON_BUILD_HW_ADDR, (const struct hw_addr_data*) { v }
|
||||
#define JSON_BUILD_STRING_SET(s) _JSON_BUILD_STRING_SET, (Set *) { s }
|
||||
#define JSON_BUILD_STRING_UNDERSCORIFY(s) _JSON_BUILD_STRING_UNDERSCORIFY, (const char *) { s }
|
||||
|
||||
#define JSON_BUILD_PAIR_UNSIGNED_NON_ZERO(name, u) _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO, (const char*) { name }, (uint64_t) { u }
|
||||
#define JSON_BUILD_PAIR_FINITE_USEC(name, u) _JSON_BUILD_PAIR_FINITE_USEC, (const char*) { name }, (usec_t) { u }
|
||||
|
@ -3500,7 +3500,8 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) {
|
||||
|
||||
switch (command) {
|
||||
|
||||
case _SD_JSON_BUILD_STRING: {
|
||||
case _SD_JSON_BUILD_STRING:
|
||||
case _JSON_BUILD_STRING_UNDERSCORIFY: {
|
||||
const char *p;
|
||||
|
||||
if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
|
||||
@ -3511,6 +3512,18 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) {
|
||||
p = va_arg(ap, const char *);
|
||||
|
||||
if (current->n_suppress == 0) {
|
||||
_cleanup_free_ char *c = NULL;
|
||||
|
||||
if (command == _JSON_BUILD_STRING_UNDERSCORIFY) {
|
||||
c = strreplace(p, "-", "_");
|
||||
if (!c) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
p = c;
|
||||
}
|
||||
|
||||
r = sd_json_variant_new_string(&add, p);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
@ -306,13 +306,17 @@ TEST(build) {
|
||||
a = sd_json_variant_unref(a);
|
||||
b = sd_json_variant_unref(b);
|
||||
|
||||
assert_se(sd_json_build(&a, SD_JSON_BUILD_OBJECT(SD_JSON_BUILD_PAIR("one", SD_JSON_BUILD_INTEGER(7)),
|
||||
SD_JSON_BUILD_PAIR("two", SD_JSON_BUILD_REAL(2.0)),
|
||||
SD_JSON_BUILD_PAIR("three", SD_JSON_BUILD_INTEGER(0)))) >= 0);
|
||||
assert_se(sd_json_buildo(&a,
|
||||
SD_JSON_BUILD_PAIR("one", SD_JSON_BUILD_INTEGER(7)),
|
||||
SD_JSON_BUILD_PAIR("two", SD_JSON_BUILD_REAL(2.0)),
|
||||
SD_JSON_BUILD_PAIR("four", JSON_BUILD_STRING_UNDERSCORIFY("foo-bar-baz")),
|
||||
SD_JSON_BUILD_PAIR("three", SD_JSON_BUILD_INTEGER(0))) >= 0);
|
||||
|
||||
assert_se(sd_json_build(&b, SD_JSON_BUILD_OBJECT(SD_JSON_BUILD_PAIR("two", SD_JSON_BUILD_INTEGER(2)),
|
||||
SD_JSON_BUILD_PAIR("three", SD_JSON_BUILD_REAL(0)),
|
||||
SD_JSON_BUILD_PAIR("one", SD_JSON_BUILD_REAL(7)))) >= 0);
|
||||
assert_se(sd_json_buildo(&b,
|
||||
SD_JSON_BUILD_PAIR("two", SD_JSON_BUILD_INTEGER(2)),
|
||||
SD_JSON_BUILD_PAIR("four", SD_JSON_BUILD_STRING("foo_bar_baz")),
|
||||
SD_JSON_BUILD_PAIR("three", SD_JSON_BUILD_REAL(0)),
|
||||
SD_JSON_BUILD_PAIR("one", SD_JSON_BUILD_REAL(7))) >= 0);
|
||||
|
||||
assert_se(sd_json_variant_equal(a, b));
|
||||
|
||||
@ -913,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[]) {
|
||||
@ -951,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,
|
||||
@ -960,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) {
|
||||
|
Loading…
Reference in New Issue
Block a user