lib: json: add helper macro for named array of array

Variant of JSON_OBJ_DESCR_ARRAY_ARRAY that can be used when the
 structure and JSON field names differ.

Signed-off-by: Bartosz Bilas <bartosz.bilas@hotmail.com>
This commit is contained in:
Bartosz Bilas 2023-07-25 19:09:15 +02:00 committed by Carles Cufí
parent f4a1d40924
commit 9ce202e50c
2 changed files with 129 additions and 0 deletions

View file

@ -401,6 +401,43 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
}, \
}
/**
* @brief Variant of JSON_OBJ_DESCR_ARRAY_ARRAY that can be used when the
* structure and JSON field names differ.
*
* This is useful when the JSON field is not a valid C identifier.
*
* @param struct_ Struct packing the values
* @param json_field_name_ String, field name in JSON strings
* @param struct_field_name_ Field name in the struct containing the array
* @param max_len_ Maximum number of elements in the array
* @param len_field_ Field name in the struct for the number of elements
* in the array
* @param elem_descr_ Element descriptor, pointer to a descriptor array
* @param elem_descr_len_ Number of elements in elem_descr_
*
* @see JSON_OBJ_DESCR_ARRAY_ARRAY
*/
#define JSON_OBJ_DESCR_ARRAY_ARRAY_NAMED(struct_, json_field_name_, struct_field_name_, \
max_len_, len_field_, elem_descr_, elem_descr_len_) \
{ \
.field_name = (#json_field_name_), \
.align_shift = Z_ALIGN_SHIFT(struct_), \
.field_name_len = sizeof(#json_field_name_) - 1, \
.type = JSON_TOK_ARRAY_START, \
.offset = offsetof(struct_, struct_field_name_), \
{ \
.array = { \
.element_descr = Z_JSON_ELEMENT_DESCR( \
struct_, len_field_, JSON_TOK_ARRAY_START, \
Z_JSON_DESCR_ARRAY( \
elem_descr_, \
1 + ZERO_OR_COMPILE_ERROR(elem_descr_len_ == 1))), \
.n_elements = (max_len_), \
}, \
}, \
}
/**
* @brief Variant of JSON_OBJ_DESCR_PRIM that can be used when the
* structure and JSON field names differ.

View file

@ -135,6 +135,14 @@ static const struct json_obj_descr array_2dim_extra_descr[] = {
ARRAY_SIZE(obj_array_descr)),
};
static const struct json_obj_descr array_2dim_extra_named_descr[] = {
JSON_OBJ_DESCR_PRIM(struct obj_array_2dim_extra, name, JSON_TOK_STRING),
JSON_OBJ_DESCR_PRIM(struct obj_array_2dim_extra, val, JSON_TOK_NUMBER),
JSON_OBJ_DESCR_ARRAY_ARRAY_NAMED(struct obj_array_2dim_extra, data, obj_array_2dim, 3,
obj_array_2dim.objects_array_array_len, obj_array_descr,
ARRAY_SIZE(obj_array_descr)),
};
ZTEST(lib_json_test, test_json_encoding)
{
struct test_struct ts = {
@ -698,6 +706,90 @@ ZTEST(lib_json_test, test_json_2dim_arr_extra_obj_encoding)
"Encoded two-dimensional extra array is not consistent");
}
ZTEST(lib_json_test, test_json_2dim_arr_extra_named_obj_encoding)
{
struct obj_array_2dim_extra obj_array_2dim_extra_ts = {
.name = "Paavo Nurmi",
.val = 123,
.obj_array_2dim.objects_array_array = {
[0] = {
.elements = {
[0] = {
.name = "Sim\303\263n Bol\303\255var",
.height = 168
},
[1] = {
.name = "Pel\303\251",
.height = 173
},
[2] = {
.name = "Usain Bolt",
.height = 195
},
},
.num_elements = 3
},
[1] = {
.elements = {
[0] = {
.name = "Muggsy Bogues",
.height = 160
},
[1] = {
.name = "Hakeem Olajuwon",
.height = 213
},
},
.num_elements = 2
},
[2] = {
.elements = {
[0] = {
.name = "Alex Honnold",
.height = 180
},
[1] = {
.name = "Hazel Findlay",
.height = 157
},
[2] = {
.name = "Daila Ojeda",
.height = 158
},
[3] = {
.name = "Albert Einstein",
.height = 172
},
},
.num_elements = 4
},
},
.obj_array_2dim.objects_array_array_len = 3,
};
char encoded[] = "{\"name\":\"Paavo Nurmi\",\"val\":123,"
"\"data\":["
"[{\"name\":\"Sim\303\263n Bol\303\255var\",\"height\":168},"
"{\"name\":\"Pel\303\251\",\"height\":173},"
"{\"name\":\"Usain Bolt\",\"height\":195}],"
"[{\"name\":\"Muggsy Bogues\",\"height\":160},"
"{\"name\":\"Hakeem Olajuwon\",\"height\":213}],"
"[{\"name\":\"Alex Honnold\",\"height\":180},"
"{\"name\":\"Hazel Findlay\",\"height\":157},"
"{\"name\":\"Daila Ojeda\",\"height\":158},"
"{\"name\":\"Albert Einstein\",\"height\":172}]"
"]}";
char buffer[sizeof(encoded)];
int ret;
ret = json_obj_encode_buf(array_2dim_extra_named_descr,
ARRAY_SIZE(array_2dim_extra_named_descr),
&obj_array_2dim_extra_ts, buffer, sizeof(buffer));
zassert_equal(ret, 0, "Encoding two-dimensional extra named array returned error");
zassert_true(!strcmp(buffer, encoded),
"Encoded two-dimensional extra named array is not consistent");
}
ZTEST(lib_json_test, test_json_2dim_obj_arr_decoding)
{
struct obj_array_2dim oaa;