google / gson

A Java serialization/deserialization library to convert Java Objects into JSON and back
Apache License 2.0
23.37k stars 4.28k forks source link

print primitive array in single line or set a line width for primitive array object #2754

Open frankfliu opened 1 month ago

frankfliu commented 1 month ago

Problem solved by the feature

When json object contains a large int[] or int[][] object, the pretty print is not useable. each element ends with newline.

Feature description

We should have an option in FormattingStyle to serialize primitive array in a single line (or even better configurable line width)

Alternatives / workarounds

Marcono1234 commented 1 month ago

We should have an option in FormattingStyle to serialize primitive array in a single line

This might not work that reliably; FormattingStyle only applies to JsonWriter, but it does not know the type of an array. The array could be heterogeneous and start with an int as first element but then contain a String or a nested array or object.

A line width could work, but probably rather as "soft" limit, so once it has been reached or exceeded the next value is written in the next line. If it was a hard limit, the writer would have to look ahead how large the next value will be or write it to a temporary buffer first before being able to decide if it has to be wrapped into the next line. Maybe this should then be called "array line width" (or any other name which includes "array") to make it clear that this only applies to arrays / array elements and not something else.

Would be interesting to see if and how other JSON libraries support this, maybe even in programming languages other than Java.

(These were just some personal thoughts on this proposal, not any specific plans to implement this yet.)

dhrax21 commented 2 weeks ago

Hey Can I work on this issue:)

Marcono1234 commented 2 weeks ago

Thanks for your offer @dhrax21!

Based on my previous https://github.com/google/gson/issues/2754#issuecomment-2395436541, I think there are currently a few open questions; maybe this needs further feedback from @frankfliu.

But what you could do, if you want, is research if / how other popular JSON libraries (for Java, but possibly also other programming languages) support this, and then document it here, including the cases where popular JSON libraries don't support it (linking to feature requests, in case there are any).

That would help better understand how commonly needed this feature is, and what good approaches for implementing this could be.

However, there is no guarantee that this feature will be implemented in the end. So no worries if you are not interested then in investigating this.

frankfliu commented 2 weeks ago

My use case is pretty simple, I want to serialize a json object than contains a image or tensor (multidimensional array). The sensor size is pretty big (like 3x1024x768), I'd like to have a semi-readable serialized format. Currently using prettyPrint is completely unusable (both performant and readability)

frankfliu commented 2 weeks ago

I found a few reference:

  1. https://www.npmjs.com/package/json-stringify-pretty-compact
  2. https://github.com/nlohmann/json/issues/229
  3. https://www.npmjs.com/package/prettier-plugin-multiline-arrays
frankfliu commented 2 weeks ago

I have a few other proposals:

  1. Adds a flag disableArrayPrettyPrint(), this will print any array type in compact format, this is not ideal, but can quickly meet some of use cases
  2. Add annotation @SerializeFormat(newline=false, indent=false, spaceAfterSeparators=true) at field level, this gives a fine-grained control to apply FormattingStyle ad field level
Marcono1234 commented 3 days ago

Thanks for the references!

I also found these:

Marcono1234 commented 3 days ago

2. Add annotation @SerializeFormat(newline=false, indent=false, spaceAfterSeparators=true) at field level, this gives a fine-grained control to apply FormattingStyle ad field level

That will probably not be possible. JSON writing and pretty-printing happens in JsonWriter, but it does not have access to annotations. Gson currently also does not include annotations in TypeToken (see #269), so type adapters would not have access to this annotation either. (I am also not sure if it would be justified to add a new annotation just for this specific use case.)


1. Adds a flag disableArrayPrettyPrint(), this will print any array type in compact format, this is not ideal, but can quickly meet some of use cases

Maybe that could indeed be a solution, or something similar to what you originally proposed above:

We should have an option in FormattingStyle to serialize primitive array in a single line

So not disable array pretty-printing in general, but based on its content (or based on the first value). My comment https://github.com/google/gson/issues/2754#issuecomment-2395436541 might have been a bit too pessimistic. Assuming that the majority of JSON arrays contains values of the same type, such an option might work well. It would be opt-in anyway, so for arrays of mixed types we could document that the exact formatting is undefined. The main question might be what we should consider as "primitive value" here: null, boolean and numbers probably yes. But strings as well? Depending on the use case they could be quite large, and it might not be desired to have them all in one line.

(These are just my personal thoughts on this though.)