json: make it easy to serialize our enums to json

Most of our enums are mapped to strings that use dashes ("-") as word
separators, i.e. "foo-bar-baz". However, Varlink enums do not allow "-"
as separator, see:

https://varlink.org/Interface-Definition

Hence, let's add some simple glue to automatucally turn "-" into "_" for
use when serializing our enums.
This commit is contained in:
Lennart Poettering 2024-06-20 09:24:18 +02:00
parent 912730a2d5
commit a556a71e9c
3 changed files with 26 additions and 7 deletions

View file

@ -130,6 +130,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 +157,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 }

View file

@ -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;

View file

@ -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));