Skip to content

Commit

Permalink
Creating a Function that Reverses a String (#796)
Browse files Browse the repository at this point in the history
Creating a reverse function for CEL that takes a string and returns a
new string whose characters are in the reverse order of the original.
  • Loading branch information
bboogler authored Aug 18, 2023
1 parent 0bd4d39 commit 5be9464
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
14 changes: 14 additions & 0 deletions ext/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,3 +414,17 @@ Examples:

'TacoCat'.upperAscii() // returns 'TACOCAT'
'TacoCÆt Xii'.upperAscii() // returns 'TACOCÆT XII'

### Reverse

Returns a new string whose characters are the same as the target string, only formatted in
reverse order.
This function relies on converting strings to rune arrays in order to reverse.
It can be located in Version 3 of strings.

<string>.reverse() -> <string>

Examples:

'gums'.reverse() // returns 'smug'
'John Smith'.reverse() // returns 'htimS nhoJ'
31 changes: 31 additions & 0 deletions ext/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,19 @@ const (
//
// 'TacoCat'.upperAscii() // returns 'TACOCAT'
// 'TacoCÆt Xii'.upperAscii() // returns 'TACOCÆT XII'
//
// # Reverse
//
// Returns a new string whose characters are the same as the target string, only formatted in
// reverse order.
// This function relies on converting strings to rune arrays in order to reverse
//
// <string>.reverse() -> <string>
//
// Examples:
//
// 'gums'.reverse() // returns 'smug'
// 'John Smith'.reverse() // returns 'htimS nhoJ'
func Strings(options ...StringsOption) cel.EnvOption {
s := &stringLib{
version: math.MaxUint32,
Expand Down Expand Up @@ -500,6 +513,16 @@ func (lib *stringLib) CompileOptions() []cel.EnvOption {
}))),
)
}
if lib.version >= 3 {
opts = append( opts,
cel.Function("reverse",
cel.MemberOverload("reverse", []*cel.Type{cel.StringType}, cel.StringType,
cel.UnaryBinding(func(str ref.Val) ref.Val {
s := str.(types.String)
return stringOrError(reverse(string(s)))
}))),
)
}
if lib.validateFormat {
opts = append(opts, cel.ASTValidators(stringFormatValidator{}))
}
Expand Down Expand Up @@ -653,6 +676,14 @@ func upperASCII(str string) (string, error) {
return string(runes), nil
}

func reverse(str string) (string, error) {
chars := []rune(str)
for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 {
chars[i], chars[j] = chars[j], chars[i]
}
return string(chars), nil
}

func joinSeparator(strs []string, separator string) (string, error) {
return strings.Join(strs, separator), nil
}
Expand Down
7 changes: 7 additions & 0 deletions ext/strings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ var stringTests = []struct {
// Upper ASCII tests.
{expr: `'tacoCat'.upperAscii() == 'TACOCAT'`},
{expr: `'tacoCαt'.upperAscii() == 'TACOCαT'`},
// Reverse tests.
{expr: `'gums'.reverse() == 'smug'`},
{expr: `'palindromes'.reverse() == 'semordnilap'`},
{expr: `'John Smith'.reverse() == 'htimS nhoJ'`},
{expr: `'u180etext'.reverse() == 'txete081u'`},
{expr: `'2600+U'.reverse() == 'U+0062'`},
{expr: `'\u180e\u200b\u200c\u200d\u2060\ufeff'.reverse() == '\ufeff\u2060\u200d\u200c\u200b\u180e'`},
// Join tests.
{expr: `['x', 'y'].join() == 'xy'`},
{expr: `['x', 'y'].join('-') == 'x-y'`},
Expand Down

0 comments on commit 5be9464

Please sign in to comment.