Skip to content

Optional dense formatting of individual arrays/objects #257

@seanmiddleditch

Description

@seanmiddleditch

Is your feature request related to a problem? Please describe.

When writing JSON files with pretty formatting, there are cases where some objects or arrays may be best formatted densely i.e. without newlines. For example, an idealized output for some data might be:

{
  "name": "Ogre Bruiser",
  "position": [ 4, 7, 8 ],
  "texture": { "$ref": "weak", "uid": "x787-5aa2" }
}

Notice the position field being displayed all on one line and the texture field as well. Expanding and indenting those values not only makes the file harder to read, but can complicate resolving merge conflicts (especially relevant combined with write flag to always write trailing commas, which is the other major issue with JSON and merge conflicts).

Describe the solution you'd like

A flag that can be attached to yyjson_mut_val objects and arrays that cause them to be serialized densely irrespective of the document formatting flags. When serialized to text and with pretty printing, the flag would suppress the newlines within the structure. This flag should probably affect all child values as well during serialization.

Spitballing, this API might look something like:

yyjson_api void yyjson_mut_val_set_dense(yyjson_mut_val *val, bool dense);

I believe the flag itself can "easily" be stored as an extra bit within the tag given the current three reserved bits available.

Describe alternatives you've considered

Instead of flags, separate types could be used, e.g. yyjson_mut_obj_dense vs yyjson_mut_obj. I don't think that's a great solution due to the explosion of public functions it would lead to, and the combinatorial explosion if other flags are ever added. This might be the right away to approach the solution in other JSON libraries, but not for yyjson.

A second alternative solution -- the one I used currently for my needs -- is to offer a separate explicit builder interface that does not use the yyjson_mut_* types at all. I don't feel that that's the kind of thing that should be added to yyjson itself, though, as even if a streaming API were added there's still valid reasons to prefer yyjson's current data structures for building an intermediate data representation.

Additional context

This would pair very nicely with #224 as well as #223, making yyjson a far better library for working with user-facing config files or data asset files.

I could see a dense flag being used as a hint for things like trying to format object keys as JSON5 short identifiers, removing the need to do an expensive string format check on every key when writing out large documents where perhaps only certain keys ever could be short identifiers (e.g. don't set the flag on key strings that are known to contain content that must be quoted).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions