ast/topdown: add strings.split_n builtin#8361
ast/topdown: add strings.split_n builtin#8361akios-ai wants to merge 2 commits intoopen-policy-agent:mainfrom
Conversation
Add strings.split_n(string, delimiter, count) builtin that splits a string into at most count substrings. This wraps Go's strings.SplitN and provides finer control than the existing split builtin. Behavior matches Go's strings.SplitN semantics: - n > 0: at most n substrings (last contains unsplit remainder) - n == 0: returns nil (empty result) - n < 0: all substrings (equivalent to split) Resolves open-policy-agent#8344 Note: This change was developed with AI assistance. Signed-off-by: aj <aj@mx4.ai>
✅ Deploy Preview for openpolicyagent ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
You'll need to run That aside, this does not seem to take the proposed handling of a negative number to mean split and limit from right-to-left into account. Was that simply missed? Anyway, looks like a good start. Thanks! |
Negative n now splits all occurrences, then returns the last |n| elements from the right side. This matches the proposal in open-policy-agent#8344 where -2 on "a;b;c;d" returns ["c", "d"]. Also runs make generate to update capabilities.json and builtin_metadata.json. Note: This change was developed with AI assistance. Signed-off-by: aj <aj@mx4.ai>
|
Good catch on the negative number — I originally followed Go's SplitN semantics where negative means "all", but the right-to-left behavior from the issue makes more sense. Fixed: negative n now splits all then takes the last |n| from the right. Also ran make generate to pick up the generated files. Thanks for the review. |
|
|
||
| p := strings.split_n("a.b.c", ".", -1) | ||
| want_result: | ||
| - x: ["c"] |
There was a problem hiding this comment.
I would have expected the right-to-left split to function exactly like the positive number variant, where the complete string is represented in the result components. I.e. if I were to do join the output on the same delimiter, I'd get back the original string: concat(".", split_n("1.2.3", ".", -1)) == "1.2.3"
E.g.
strings.split_n("a.b.c", ".", -1) = ["a.b.c"]strings.split_n("a.b.c", ".", -2) = ["a.b", "c"]strings.split_n("a.b.c", ".", -3) = ["a", "b", "c"]
There was a problem hiding this comment.
Neither version should keep any remaining parts of the string, but this should mean "split and return the first n results" from either left or right.
There was a problem hiding this comment.
To clarify: my comment here is about the discrepancy in behavior between positive and negative ns. If we're supposed to be dropping the "remainder" tail, e.g. strings.split_n("a.b.c.d", ".", 2) = ["a", "b"]; that's fine. It just should behave the same in both directions :)
|
This pull request has been automatically marked as stale because it has not had any activity in the last 30 days. |
Adds
strings.split_n(string, delimiter, count)— wraps Go'sstrings.SplitN.The existing
splitbuiltin always splits on every occurrence. This gives policies control over how many splits happen, which is useful when parsing structured strings where only the first (or first N) delimiters matter.Semantics match Go's
strings.SplitN:n > 0: at most n substrings, last one gets the remaindern == 0: niln < 0: all substrings (same assplit)Example:
Closes #8344
This change was developed with AI assistance.