Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow configuring spaces before and/or after the colon in DefaultPrettyPrinter #1042

Merged

Conversation

digulla
Copy link
Contributor

@digulla digulla commented Jun 6, 2023

No description provided.

@digulla
Copy link
Contributor Author

digulla commented Jun 6, 2023

I tried to keep the behavior the same but looking at the broken unit tests, this approach doesn't work very well.

Suggestions how to proceed? Change the tests and risk breaking existing code or create a new, parallel API and deprecate the old ones?

@cowtowncoder
Copy link
Member

Yeah this is tricky; whether it's possible to change, in a backwards-compatible way, behavior of DefaultPrettyPrinter.
Especially when Separators is sort-of, kind-of part of public API.

I would probably implement alternate PrettyPrinter implementation, not trying to change existing implementations.

Alternatively if you do want to try to change DefaultPrettyPrinter, I'd be deprecated older methods, add new ones.
I do feel that ability to change spacing around : is useful since ": " seems to be commonly preferred over " : ".

@digulla
Copy link
Contributor Author

digulla commented Jun 6, 2023

My second idea was to add a boolean spaceBeforeColon which DefaultPrettyPrinter would then read. But some of the spaces handling is in DefaultPrettyPrinter in _withSpaces() and the flag _spacesInObjectEntries.

I think a cleaner approach would be when Separators would contain all the config but I'm not sure whether I can pull that off since the duties are so mixed. I'll try again in the next days.

@cowtowncoder
Copy link
Member

@digulla Yeah, apologies for the mess here: division of responsibilities is not well defined for sure. I hope we can figure this out. Ability to include space before and/or after colon sounds like reasonable if it's possible to retro-fit somehow. I assume at least 3 out of 4 combinations would be widely enough used.

@cowtowncoder
Copy link
Member

cowtowncoder commented Jun 7, 2023

@digulla Ok, looking at Separators / pretty-printers, I agree that Separators probably should have new method(s) for returning "full" separators, in which possible surrounding spaces (if any) are included. Ideally all 3 existing methods would have counterparts, but for now I assume we just need one.
Existing methods would remain, but I think one(s) with overrides should be deprecated, likely.

Now, whether "full" value should be indicated by String containing space, enumeration (4 combinations for pre-/after of single space), or 2 boolean flags per settings I don't know. It might be simplest to just add full String to keep number of settings limited.
Note that default Separators used by MinimalPrettyPrinter would differ from those of DefaultPrettyPrinter: former is compact (no spaces), latter has spaces.

Maybe I could try outlining how I see this working unless you get there first.

EDIT: although, TBH, adding configuration in DefaultPrettyPrinter, as part of calculation of _objectFieldValueSeparatorWithSpaces does look deceptively simple as well. So perhaps that's not a bad alternative; adding an enum outlining combinations of space before/after Object value separator (key/value separator).

@digulla
Copy link
Contributor Author

digulla commented Jun 7, 2023

I also think we could have a boolean flag which controls the space before the colon but it would make the code even more confusing than it already is.

How about a new implementation for both and deprecating the old ones for 3.x?

I would use PrettyPrinterConfig for the separator strings and StandardPrettyPrinter for the implementation? The config should contain all spaces and the indenters plus a builder to set it up with two defaults (minimal and the current pretty printer).

This one is much cleaner than the first attempt but we have to decide which PrettyPrinter config to break: Either the default Separators is with spaces around the colon, then MinimalPrettyPrinter has to modify the default. Or the default is without spaces, then DefaultPrettyPrinter has to modify it.

Of course, this affects anyone who tries to build their own PrettyPrinter using the default Separators.
@digulla
Copy link
Contributor Author

digulla commented Jun 7, 2023

I've rolled back the incompatible changes and introduced a new Spacing enum. This allows for much cleaner code but one of MinimalPrettyPrinter or DefaultPrettyPrinter can't use Separators.createDefaultInstance() anymore.

Right now, I think is the way to go. DefaultPrettyPrinter should cache the separators instead of calling apply() all the time and all the spacing options in DefaultPrettyPrinter should be deprecated.

@@ -255,7 +255,8 @@ protected DefaultPrettyPrinter _withSpaces(boolean state)
*/
public DefaultPrettyPrinter withSeparators(Separators separators) {
_separators = separators;
_objectFieldValueSeparatorWithSpaces = " " + separators.getObjectFieldValueSeparator() + " ";
_objectFieldValueSeparatorWithSpaces = separators.getObjectFieldValueSpacing().apply(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For performance reasons, let's also add the other 2 "WithSpaces" fields that are missing to avoid calling apply() on those cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@cowtowncoder
Copy link
Member

@digulla I agree this is the way to go. We do need to eliminate calls to apply(), f.ex by adding 2 more fields in DefaultPrettyPrinter. And yes, should deprecate old configuration.

I am hoping to get this merged soon, thank you for working through all the ideas here.

Deprecated old API.
Tests for old and new API to make sure the changes don't break existing code and the new API can do what the old could.
@digulla
Copy link
Contributor Author

digulla commented Jun 13, 2023

Okay, I feel we're making progress. Have a look at the latest version. It should address all your concerns.

I'm not sure what to do with SerializedString used only for rootSeparator. String is already perfectly serializable; what is the purpose of this class? Should I always use SerializedString? But then, why do the existing fields in DefaultPrettyPrinter mix String and SerializedString?

Converted all tests that used the old API.
Copy link
Member

@cowtowncoder cowtowncoder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good -- I hope I can figure out how to merge it in master/3.0.

@cowtowncoder cowtowncoder changed the title Allow to configure the space before the colon in DefaultPrettyPrinter. Allow configuring spaces before and/or after the colon in DefaultPrettyPrinter Jun 13, 2023
@cowtowncoder cowtowncoder merged commit 23aee01 into FasterXML:2.16 Jun 13, 2023
5 checks passed
cowtowncoder added a commit that referenced this pull request Jun 13, 2023
@cowtowncoder
Copy link
Member

Ok, merged up to master (phew!). Master has a few renamings which complicated things but it should be all good now.

@digulla digulla deleted the allow_to_configure_space_before_colon branch June 14, 2023 19:46
@digulla
Copy link
Contributor Author

digulla commented Jun 14, 2023

Hey, thanks. It was nice working with you on this.

@cowtowncoder
Copy link
Member

@digulla My pleasure, thank you for going through twists & turns :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants