Skip to content

Commit

Permalink
fix: Match OPA behavior for split (#295)
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 <anakrish@microsoft.com>
  • Loading branch information
anakrish authored Aug 8, 2024
1 parent e4a58ad commit a488a84
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/builtins/strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,18 @@ 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(
// Handle https://github.com/microsoft/regorus/issues/291
let parts: Vec<Value> = if delimiter.as_ref() == "" {
// If delimiter is "", str::split returns a leading and trailing "" whereas Golang's split doesn't.
// Therefore avoid str::split and instead return each char as a Value::String.
s.chars().map(|c| Value::from(c.to_string())).collect()
} else {
s.split(delimiter.as_ref())
.map(|s| Value::String(s.into()))
.collect(),
))
.collect()
};

Ok(Value::from(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 a488a84

Please sign in to comment.