danielaparker / jsoncons

A C++, header-only library for constructing JSON and JSON-like data formats, with JSON Pointer, JSON Patch, JSON Schema, JSONPath, JMESPath, CSV, MessagePack, CBOR, BSON, UBJSON
https://danielaparker.github.io/jsoncons
Other
697 stars 160 forks source link

The spaces_around_comma options doesn't work #490

Closed YintongMa closed 4 months ago

YintongMa commented 6 months ago

I want print out the json array by adding a space after comma. But the spaces_around_comma option doesn't work in the following simple case. `
Code:

jsoncons::json j_arr(jsoncons::json_array_arg, {"1", "2", 3, 4});
jsoncons::json_options options;
options.spaces_around_comma(jsoncons::spaces_option::space_after);
std::string buffer;
jsoncons::encode_json(j_arr, buffer, options);
std::cout << buffer << std::endl;

`

The output is: ["1","2",3,4]

What I want is: ["1", "2", 3, 4]

danielaparker commented 6 months ago

Thanks for reporting this, I'll have a look.

danielaparker commented 6 months ago

It's been a while since I've looked at the json options! I had to re-familiarize myself with them.

The function encode_json with indenting::no_indent as the (default) fourth argument doesn't perform any prettify operations on the output json, it produces compact single-line output only, and ignores prettify options (by design.) To prettify the output, with spaces and so on, you need to call it with indenting::indent.

If your input JSON looked like

[["1", "2"], [3, 4]]

you could use

   jsoncons::json_options options;
   options.spaces_around_comma(jsoncons::spaces_option::space_after);
   options.array_array_line_splits(jsoncons::line_split_kind::same_line);
   std::string buffer;
   jsoncons::encode_json(j_arr, buffer, options, jsoncons::indenting::indent);
   std::cout << buffer << std::endl;

and your output would be

[
    ["1", "2"],
    [3, 4]
]

It seems we don't currently have an option for prettifying the output but leaving it on a single line.

The name of the fourth parameter type indenting is a little misleading, it really means "prettify yes no", that usually does include line indenting, but not in your case.

YintongMa commented 6 months ago

Thank you so much for the help! I think I'll iterate the values and format the output by myself then

danielaparker commented 6 months ago

This is now supported on the branch master, with the new option line_splits,

    jsoncons::json j_arr = jsoncons::json::parse(R"(["1", "2", 3, 4])");
    jsoncons::json_options options;
    options.spaces_around_comma(jsoncons::spaces_option::space_after) // same as default when using pretty printing 
           .line_splits(jsoncons::line_split_kind::same_line);        // default is multi_line 
    std::string buffer;
    jsoncons::encode_json(j_arr, buffer, options, jsoncons::indenting::indent);
    std::cout << buffer << std::endl;

Output:

["1", "2", 3, 4]

The line_splits value now becomes the default value for object_object_line_splits, object_array_line_splits, array_object_line_splits, and array_array_line_splits, so, for example,

    jsoncons::json j_arr = jsoncons::json::parse(R"(["1", "2", [3, 4]])");
    jsoncons::json_options options;
    options.line_splits(jsoncons::line_split_kind::same_line);
    std::string buffer;
    jsoncons::encode_json(j_arr, buffer, options, jsoncons::indenting::indent);
    std::cout << buffer << std::endl;

produces

["1", "2", [3, 4]]
YintongMa commented 6 months ago

That's awsome! Appreciated it!