Skip to content

Commit deee5fd

Browse files
committed
Resolve remarks
1 parent 0c7693f commit deee5fd

File tree

4 files changed

+45
-24
lines changed

4 files changed

+45
-24
lines changed

docs/reference/schemas/config/functions/skip.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ specified number of items from the start.
2626
- For strings: returns a new string containing characters after the specified index
2727

2828
Both parameters are required. `originalValue` must be an array or a string.
29-
`numberToSkip` must be an integer greater than or equal to zero. If the number
30-
is greater than the length of the array or string, the function returns an
31-
empty array or an empty string respectively.
29+
`numberToSkip` must be an integer; negative values are treated as zero. If the
30+
number is greater than the length of the array or string, the function returns
31+
an empty array or an empty string respectively.
3232

3333
## Examples
3434

@@ -112,7 +112,8 @@ Position: 1
112112
113113
### numberToSkip
114114
115-
The number of items to skip from the start. Must be a non-negative integer.
115+
The number of items to skip from the start. Must be an integer. Negative values
116+
are treated as zero.
116117
117118
```yaml
118119
Type: int
@@ -135,7 +136,6 @@ Type: array | string
135136

136137
- `originalValue` is not an array or string
137138
- `numberToSkip` is not an integer
138-
- `numberToSkip` is negative
139139

140140
## Related functions
141141

dsc/tests/dsc_functions.tests.ps1

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,13 @@ Describe 'tests for function expressions' {
412412
It 'skip function works for: <expression>' -TestCases @(
413413
@{ expression = "[skip(createArray('a','b','c','d'), 2)]"; expected = @('c','d') }
414414
@{ expression = "[skip('hello', 2)]"; expected = 'llo' }
415-
@{ expression = "[skip(createArray('a'), 0)]"; expected = @('a') }
416-
@{ expression = "[skip('a', 0)]"; expected = 'a' }
415+
@{ expression = "[skip(createArray('a','b'), 0)]"; expected = @('a','b') }
416+
@{ expression = "[skip('abc', 0)]"; expected = 'abc' }
417417
@{ expression = "[skip(createArray('a','b'), 5)]"; expected = @() }
418418
@{ expression = "[skip('', 1)]"; expected = '' }
419+
# Negative counts are treated as zero
420+
@{ expression = "[skip(createArray('x','y'), -3)]"; expected = @('x','y') }
421+
@{ expression = "[skip('xy', -1)]"; expected = 'xy' }
419422
) {
420423
param($expression, $expected)
421424

dsc_lib/locales/en-us.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,6 @@ invoked = "startsWith function"
409409
description = "Returns an array with all elements after the specified number, or a string with all characters after the specified number"
410410
invoked = "skip function"
411411
invalidNumberToSkip = "Second argument must be an integer"
412-
negativeNotAllowed = "Second argument cannot be negative"
413412
invalidOriginalValue = "First argument must be an array or string"
414413

415414
[functions.string]

dsc_lib/src/functions/skip.rs

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,27 +31,28 @@ impl Function for Skip {
3131
fn invoke(&self, args: &[Value], _context: &Context) -> Result<Value, DscError> {
3232
debug!("{}", t!("functions.skip.invoked"));
3333

34-
let Some(count_i64) = args[1].as_i64() else {
35-
return Err(DscError::Parser(t!("functions.skip.invalidNumberToSkip").to_string()));
36-
};
37-
if count_i64 < 0 {
38-
return Err(DscError::Parser(t!("functions.skip.negativeNotAllowed").to_string()));
39-
}
40-
let count: usize = count_i64.try_into().unwrap_or(usize::MAX);
34+
if let Some(count_i64) = args[1].as_i64() {
35+
let count: usize = if count_i64 < 0 {
36+
0
37+
} else {
38+
count_i64.try_into().unwrap_or(usize::MAX)
39+
};
4140

42-
if let Some(array) = args[0].as_array() {
43-
if count >= array.len() { return Ok(Value::Array(vec![])); }
44-
let skipped = array.iter().skip(count).cloned().collect::<Vec<Value>>();
45-
return Ok(Value::Array(skipped));
46-
}
41+
if let Some(array) = args[0].as_array() {
42+
if count >= array.len() { return Ok(Value::Array(vec![])); }
43+
let skipped = array.iter().skip(count).cloned().collect::<Vec<Value>>();
44+
return Ok(Value::Array(skipped));
45+
}
4746

48-
if let Some(s) = args[0].as_str() {
47+
if let Some(s) = args[0].as_str() {
48+
let result: String = s.chars().skip(count).collect();
49+
return Ok(Value::String(result));
50+
}
4951

50-
let result: String = s.chars().skip(count).collect();
51-
return Ok(Value::String(result));
52+
return Err(DscError::Parser(t!("functions.skip.invalidOriginalValue").to_string()));
5253
}
5354

54-
Err(DscError::Parser(t!("functions.skip.invalidOriginalValue").to_string()))
55+
Err(DscError::Parser(t!("functions.skip.invalidNumberToSkip").to_string()))
5556
}
5657
}
5758

@@ -81,4 +82,22 @@ mod tests {
8182
let result = parser.parse_and_execute("[skip(createArray('a','b'), 5)]", &Context::new()).unwrap();
8283
assert_eq!(result, Value::Array(vec![]));
8384
}
85+
86+
#[test]
87+
fn skip_array_negative_is_zero() {
88+
let mut parser = Statement::new().unwrap();
89+
let result = parser.parse_and_execute("[skip(createArray('a','b','c'), -1)]", &Context::new()).unwrap();
90+
assert_eq!(result, Value::Array(vec![
91+
Value::String("a".into()),
92+
Value::String("b".into()),
93+
Value::String("c".into()),
94+
]));
95+
}
96+
97+
#[test]
98+
fn skip_string_negative_is_zero() {
99+
let mut parser = Statement::new().unwrap();
100+
let result = parser.parse_and_execute("[skip('ab', -2)]", &Context::new()).unwrap();
101+
assert_eq!(result, Value::String("ab".into()));
102+
}
84103
}

0 commit comments

Comments
 (0)