Now that we can visit any QObject, it's easy to add support for visit_type_any() in the JSON output visitor.
Signed-off-by: Eric Blake <ebl...@redhat.com> --- v4: new patch, split out of v3 7/18, but made simpler by not requiring v3 12/18 --- include/qapi/json-output-visitor.h | 2 -- qapi/json-output-visitor.c | 7 ++++++ tests/test-json-output-visitor.c | 50 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/include/qapi/json-output-visitor.h b/include/qapi/json-output-visitor.h index 94c9e0f..414f91b 100644 --- a/include/qapi/json-output-visitor.h +++ b/include/qapi/json-output-visitor.h @@ -23,8 +23,6 @@ typedef struct JsonOutputVisitor JsonOutputVisitor; * * If @pretty, make the output legible with newlines and indentation; * otherwise the output uses a single line. - * - * For now, this cannot be used to visit the 'any' type. */ Visitor *json_output_visitor_new(bool pretty, char **result); diff --git a/qapi/json-output-visitor.c b/qapi/json-output-visitor.c index 881c9ee..ba647d3 100644 --- a/qapi/json-output-visitor.c +++ b/qapi/json-output-visitor.c @@ -147,6 +147,12 @@ static void json_output_type_number(Visitor *v, const char *name, double *obj, qstring_append_json_number(jov->str, *obj); } +static void json_output_type_any(Visitor *v, const char *name, QObject **obj, + Error **errp) +{ + qobject_visit_output(v, name, *obj); +} + static void json_output_type_null(Visitor *v, const char *name, Error **errp) { JsonOutputVisitor *jov = to_jov(v); @@ -196,6 +202,7 @@ Visitor *json_output_visitor_new(bool pretty, char **result) v->visitor.type_bool = json_output_type_bool; v->visitor.type_str = json_output_type_str; v->visitor.type_number = json_output_type_number; + v->visitor.type_any = json_output_type_any; v->visitor.type_null = json_output_type_null; v->visitor.complete = json_output_complete; v->visitor.free = json_output_free; diff --git a/tests/test-json-output-visitor.c b/tests/test-json-output-visitor.c index 5073715..fd14e26 100644 --- a/tests/test-json-output-visitor.c +++ b/tests/test-json-output-visitor.c @@ -316,6 +316,52 @@ static void test_visitor_out_list(TestOutputVisitorData *data, qapi_free_TestStructList(head); } +static void test_visitor_out_any(TestOutputVisitorData *data, + const void *arg) +{ + const bool *pretty = arg; + QObject *qobj; + QDict *qdict; + const char *out; + + qobj = QOBJECT(qint_from_int(-42)); + visit_type_any(data->ov, NULL, &qobj, &error_abort); + out = visitor_get(data); + g_assert_cmpstr(out, ==, "-42"); + qobject_decref(qobj); + + visitor_reset(data); + qdict = qdict_new(); + /* Ordering here is sensitive to the hashing chosen by QDict. */ + qdict_put(qdict, "integer", qint_from_int(-42)); + qdict_put(qdict, "list", qlist_new()); + qdict_put(qdict, "boolean", qbool_from_bool(true)); + qdict_put(qdict, "string", qstring_from_str("foo")); + qobj = QOBJECT(qdict); + visit_type_any(data->ov, NULL, &qobj, &error_abort); + qobject_decref(qobj); + out = visitor_get(data); + + if (*pretty) { + g_assert_cmpstr(out, ==, + "{\n" + " \"integer\": -42,\n" + " \"list\": [\n" + " ],\n" + " \"boolean\": true,\n" + " \"string\": \"foo\"\n" + "}"); + } else { + g_assert_cmpstr(out, ==, + "{" + "\"integer\": -42, " + "\"list\": [], " + "\"boolean\": true, " + "\"string\": \"foo\"" + "}"); + } +} + static void test_visitor_out_union_flat(TestOutputVisitorData *data, const void *unused) { @@ -412,6 +458,10 @@ int main(int argc, char **argv) test_visitor_out_struct_errors); output_visitor_test_add("/visitor/json/list", &plain, test_visitor_out_list); + output_visitor_test_add("/visitor/json/any", &plain, + test_visitor_out_any); + output_visitor_test_add("/visitor/json-pretty/any", &pretty, + test_visitor_out_any); output_visitor_test_add("/visitor/json/union-flat", &plain, test_visitor_out_union_flat); output_visitor_test_add("/visitor/json/alternate", &plain, -- 2.5.5