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 the visitor to cease callbacks #88

Merged
merged 4 commits into from
Jun 24, 2024

Conversation

Vbbab
Copy link
Contributor

@Vbbab Vbbab commented May 14, 2024

As per #30, this PR implements a new feature whereby the callbacks for onObjectBegin and onArrayBegin for the JSONVisitor may return a boolean (rather than an arbitrary ignored value as was previously the case) which indicates whether the visitor should continue receiving callbacks for the subtree.

As an example, consider the following JSON:

{
    "a": {
        "b": [ {
            "c": "d",
            "e": "f",
        } ]
    }
}

If, upon receiving the onArrayBegin callback from the array of b, the user returns false from the callback, then all other callbacks for everything within the array will be suppressed, and the next callback the user receives will only be the corresponding onArrayEnd.

Internally, this works by keeping a counter suppressedCallbacks within visit(), which keeps track of the "depth" of the subtree where callbacks are being suppressed. When a new onXXXBegin() callback is called and this depth is nonzero, it is incremented. Similarly, when an onXXXEnd() callback is called, the depth is decremented, and callbacks are only called when the counter is 0. This also meant creating new callback adapters (?) such as toBeginVisit and toEndVisit that handle this counter logic on top of wrapping the actual callback. These were modeled after the original toNoArgVisitWithPath/toNoArgVisit functions.

FWIW, I've changed the return type of the two begin callbacks to boolean | void rather than just boolean, so as to preserve some backward compatibility for users who weren't just returning garbage from the callbacks. However, this also meant some refactoring to other parts of the codebase that didn't quite comply with a strict void return.

I've also added additional parameters to the assertVisit function to test stopping callbacks at a certain position within the JSON (as long as an onArrayBegin or onObjectBegin callback can be triggered at the specified position). In order to adapt the fact that the begin callbacks now return booleans, I added a beginHalder which handles the logic of returning false when appropriate.

I'd appreciate it if you would be kind enough to review my code. Let me know what you think!
Thank you!

@aeschli
Copy link
Contributor

aeschli commented Jun 24, 2024

Thanks @Vbbab, looks good! I made some small code polishes.

@aeschli aeschli self-assigned this Jun 24, 2024
@aeschli aeschli added this to the June 2024 milestone Jun 24, 2024
@aeschli aeschli enabled auto-merge (squash) June 24, 2024 14:42
@aeschli aeschli merged commit 9e24580 into microsoft:main Jun 24, 2024
2 checks passed
@Vbbab
Copy link
Contributor Author

Vbbab commented Jun 25, 2024

Alright, thank you so much!

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.

3 participants