Skip to content

Commit

Permalink
Extensions README.md for non-Go devs (#320)
Browse files Browse the repository at this point in the history
* Extensions README.md for non-Go devs
* Updates to the docs and an another test.
  • Loading branch information
TristonianJones authored Mar 10, 2020
1 parent f423b48 commit 0296b62
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 4 deletions.
139 changes: 139 additions & 0 deletions ext/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Extensions

CEL extensions are a related set of constants, functions, macros, or other
features which may not be covered by the core CEL spec.

## Strings

Extended functions for string manipulation. As a general note, all indices are
zero-based.

### CharAt

Returns the character at the given position. If the position is negative, or
greater than the length of the string, the function will produce an error:

<string>.charAt(<int>) -> <string>

Examples:

'hello'.charAt(4) // return 'o'
'hello'.charAt(5) // return ''
'hello'.charAt(-1) // error


### IndexOf

Returns the integer index of the first occurrence of the search string. If the
search string is not found the function returns -1.

The function also accepts an optional position from which to begin the
substring search. If the substring is the empty string, the index where the
search starts is returned (zero or custom).

<string>.indexOf(<string>) -> <int>
<string>.indexOf(<string>, <int>) -> <int>

Examples:

'hello mellow'.indexOf('') // returns 0
'hello mellow'.indexOf('ello') // returns 1
'hello mellow'.indexOf('jello') // returns -1
'hello mellow'.indexOf('', 2) // returns 2
'hello mellow'.indexOf('ello', 2) // returns 7
'hello mellow'.indexOf('ello', 20) // error

### LastIndexOf

Returns the integer index of the last occurrence of the search string. If the
search string is not found the function returns -1.

The function also accepts an optional position which represents the last index
to be considered as the beginning of the substring match. If the substring is
the empty string, the index where the search starts is returned (string length
or custom).

<string>.lastIndexOf(<string>) -> <int>
<string>.lastIndexOf(<string>, <int>) -> <int>

Examples:

'hello mellow'.lastIndexOf('') // returns 12
'hello mellow'.lastIndexOf('ello') // returns 7
'hello mellow'.lastIndexOf('jello') // returns -1
'hello mellow'.lastIndexOf('ello', 6) // returns 1
'hello mellow'.lastIndexOf('ello', -1) // error

### Replace

Produces a new string based on the target, which replaces the occurrences of a
search string with a replacement string if present. The function accepts an
optional limit on the number of substring replacements to be made.

When the replacement limit is 0, the result is the original string. When the
limit is a negative number, the function behaves the same as replace all.

<string>.replace(<string>, <string>) -> <string>
<string>.replace(<string>, <string>, <int>) -> <string>

Examples:

'hello hello'.replace('he', 'we') // returns 'wello wello'
'hello hello'.replace('he', 'we', -1) // returns 'wello wello'
'hello hello'.replace('he', 'we', 1) // returns 'wello hello'
'hello hello'.replace('he', 'we', 0) // returns 'hello hello'

### Split

Produces a list of strings split from the input by the given separator. The
function accepts an optional argument specifying a limit on the number of
substrings produced by the split.

When the split limit is 0, the result is an empty list. When the limit is 1,
the result is the target string to split. When the limit is a negative
number, the function behaves the same as split all.

<string>.split(<string>) -> <list<string>>
<string>.split(<string>, <int>) -> <list<string>>

Examples:

'hello hello hello'.split(' ') // returns ['hello', 'hello', 'hello']
'hello hello hello'.split(' ', 0) // returns []
'hello hello hello'.split(' ', 1) // returns ['hello hello hello']
'hello hello hello'.split(' ', 2) // returns ['hello', 'hello hello']
'hello hello hello'.split(' ', -1) // returns ['hello', 'hello', 'hello']

### Substring

Returns the substring given a numeric range corresponding to character
positions. Optionally may omit the trailing range for a substring from a given
character position until the end of a string.

Character offsets are 0-based with an inclusive start range and exclusive end
range. It is an error to specify an end range that is lower than the start
range, or for either the start or end index to be negative or exceed the string
length.

<string>.substring(<int>) -> <string>
<string>.substring(<int>, <int>) -> <string>

Examples:

'tacocat'.substring(4) // returns 'cat'
'tacocat'.substring(0, 4) // returns 'taco'
'tacocat'.substring(-1) // error
'tacocat'.substring(2, 1) // error

### Trim

Returns a new string which removes the leading and trailing whitespace in the
target string. The trim function uses the Unicode definition of whitespace
which does not include the zero-width spaces. See:
https://en.wikipedia.org/wiki/Whitespace_character#Unicode

<string>.trim() -> <string>

Examples:

' \ttrim\n '.trim() // returns 'trim'
8 changes: 4 additions & 4 deletions ext/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import (
// Returns the integer index of the first occurrence of the search string. If the search string is
// not found the function returns -1.
//
// The function also accepts an optional index from which to begin the substring search. If the
// The function also accepts an optional position from which to begin the substring search. If the
// substring is the empty string, the index where the search starts is returned (zero or custom).
//
// <string>.indexOf(<string>) -> <int>
Expand All @@ -71,9 +71,9 @@ import (
// Returns the integer index at the start of the last occurrence of the search string. If the
// search string is not found the function returns -1.
//
// The function also accepts an optional index which represents where to begin the substring
// search starting from the end of the string. If the substring is the empty string, the index
// where the search starts is returned (string length or custom).
// The function also accepts an optional position which represents the last index to be
// considered as the beginning of the substring match. If the substring is the empty string,
// the index where the search starts is returned (string length or custom).
//
// <string>.lastIndexOf(<string>) -> <int>
// <string>.lastIndexOf(<string>, <int>) -> <int>
Expand Down
1 change: 1 addition & 0 deletions ext/strings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ var stringTests = []struct {
{expr: `'hello wello'.lastIndexOf('elbo room!!') == -1`},
{expr: `'hello wello'.lastIndexOf('elbo room!!!') == -1`},
{expr: `'hello wello'.lastIndexOf('hello wello') == 0`},
{expr: `'bananananana'.lastIndexOf('nana', 7) == 6`},
// Replace tests
{expr: `"12 days 12 hours".replace("{0}", "2") == "12 days 12 hours"`},
{expr: `"{0} days {0} hours".replace("{0}", "2") == "2 days 2 hours"`},
Expand Down

0 comments on commit 0296b62

Please sign in to comment.