Skip to content

Commit

Permalink
fix: Match OPA behavior for split
Browse files Browse the repository at this point in the history
In case of empty delimiter, Rust's split returns leading and trailing
empty strings whereas Golang's doesn't.
Change behavior to match Golang/OPA.

fixes #291

Signed-off-by: Anand Krishnamoorthi <[email protected]>
  • Loading branch information
anakrish committed Aug 8, 2024
1 parent e4a58ad commit 6c61445
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 5 deletions.
31 changes: 26 additions & 5 deletions src/builtins/strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,32 @@ fn split(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) -> Re
let s = ensure_string(name, &params[0], &args[0])?;
let delimiter = ensure_string(name, &params[1], &args[1])?;

Ok(Value::from_array(
s.split(delimiter.as_ref())
.map(|s| Value::String(s.into()))
.collect(),
))
let mut parts: Vec<Value> = s
.split(delimiter.as_ref())
.map(|s| Value::String(s.into()))
.collect();

// Handle https://github.com/microsoft/regorus/issues/291
// If delimiter is "", rust returns a leading and trailing "", Golang doesn't.
if delimiter.as_ref() == "" {
if parts.len() >= 2 {
if let ("", "") = (
parts[0].as_string()?.as_ref(),
parts[parts.len() - 1].as_string()?.as_ref(),
) {
// Remove trailing and leading "".
parts.pop();
parts.remove(0);
return Ok(Value::from_array(parts));
}
}

bail!(span.error(
"split with empty delimiter did not return leading and trailing empty delimiters"
));
}

Ok(Value::from_array(parts))
}

fn to_string(v: &Value, unescape: bool) -> String {
Expand Down
17 changes: 17 additions & 0 deletions tests/interpreter/cases/builtins/strings/split.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

cases:
- note: empty separator
data: {}
modules: []
query: "x := split(\"test\", \"\")"
want_result:
x: ["t", "e", "s", "t"]

- note: empty separator, empty string
data: {}
modules: []
query: "x := split(\"\", \"\")"
want_result:
x: []

0 comments on commit 6c61445

Please sign in to comment.