Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update REPL to use ext.Strings formatter when possible. #659

Merged
merged 1 commit into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions ext/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ func clauseForType(argType ref.Type) (clauseImpl, error) {
case types.IntType, types.UintType:
return formatDecimal, nil
case types.StringType, types.BytesType, types.BoolType, types.NullType, types.TypeType:
return formatString, nil
return FormatString, nil
case types.TimestampType, types.DurationType:
// special case to ensure timestamps/durations get printed as CEL literals
return func(arg ref.Val, locale string) (string, error) {
Expand Down Expand Up @@ -770,7 +770,7 @@ func formatMap(arg ref.Val, locale string) (string, error) {
var keyFormat clauseImpl
switch key.Type() {
case types.StringType, types.BoolType:
keyFormat = formatString
keyFormat = FormatString
case types.IntType, types.UintType:
keyFormat = formatDecimal
default:
Expand Down Expand Up @@ -844,7 +844,10 @@ func quoteForCEL(refVal ref.Val, unquotedValue string) string {
}
}

func formatString(arg ref.Val, locale string) (string, error) {
// FormatString returns the string representation of a CEL value.
// It is used to implement the %s specifier in the (string).format() extension
// function.
func FormatString(arg ref.Val, locale string) (string, error) {
switch arg.Type() {
case types.ListType:
return formatList(arg, locale)
Expand Down Expand Up @@ -1018,7 +1021,7 @@ func parseFormattingClause(lastStrIndex int, formatStr string) (int, clauseImpl,
i++
switch r {
case 's':
return i, formatString, nil
return i, FormatString, nil
case 'd':
return i, formatDecimal, nil
case 'f':
Expand Down
1 change: 1 addition & 0 deletions repl/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ go_library(
"//checker/decls:go_default_library",
"//common/types:go_default_library",
"//common/types/ref:go_default_library",
"//ext:go_default_library",
"//interpreter:go_default_library",
"//interpreter/functions:go_default_library",
"//repl/parser:go_default_library",
Expand Down
9 changes: 8 additions & 1 deletion repl/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/google/cel-go/checker/decls"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/ext"
"github.com/google/cel-go/interpreter"
"github.com/google/cel-go/interpreter/functions"

Expand Down Expand Up @@ -758,7 +759,13 @@ func (e *Evaluator) Process(cmd Cmder) (string, bool, error) {
return "", false, fmt.Errorf("expr failed:\n%v", err)
}
if val != nil {
return fmt.Sprintf("%v : %s", val.Value(), UnparseType(resultT)), false, nil
t := UnparseType(resultT)
v, err := ext.FormatString(val, "")
if err != nil {
// Default format if type is unsupported by ext.Strings formatter.
return fmt.Sprintf("%v : %s", val.Value(), t), false, nil
}
return fmt.Sprintf("%s : %s", v, t), false, nil
}
case *letVarCmd:
var err error
Expand Down
44 changes: 44 additions & 0 deletions repl/evaluator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,50 @@ func TestProcess(t *testing.T) {
wantExit bool
wantError bool
}{
{
name: "FormatNumberResult",
commands: []Cmder{
&evalCmd{
expr: "1u + 2u",
},
},
wantText: "3 : uint",
wantExit: false,
wantError: false,
},
{
name: "FormatStringResult",
commands: []Cmder{
&evalCmd{
expr: `'a' + r'b\1'`,
},
},
wantText: `ab\1 : string`,
wantExit: false,
wantError: false,
},
{
name: "FormatListResult",
commands: []Cmder{
&evalCmd{
expr: `['abc', 123, 3.14, duration('2m')]`,
},
},
wantText: `["abc", 123, 3.140000, duration("120s")] : list(dyn)`,
wantExit: false,
wantError: false,
},
{
name: "FormatMapResult",
commands: []Cmder{
&evalCmd{
expr: `{1: 123, 2: 3.14, 3: duration('2m'), 4: b'123'}`,
},
},
wantText: `{1:123, 2:3.140000, 3:duration("120s"), 4:b"123"} : map(int, dyn)`,
wantExit: false,
wantError: false,
},
{
name: "OptionBasic",
commands: []Cmder{
Expand Down