Skip to content
This repository was archived by the owner on Aug 23, 2023. It is now read-only.

Commit 0428430

Browse files
authored
Merge pull request #895 from bloomberg/feature_strBool
Accept bool strings for ArgBool
2 parents 1003db8 + 954fd2b commit 0428430

File tree

4 files changed

+84
-12
lines changed

4 files changed

+84
-12
lines changed

expr/expr.go

+20-6
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,17 @@ func (e expr) consumeBasicArg(pos int, exp Arg) (int, error) {
149149
}
150150
*v.val = re
151151
case ArgBool:
152-
if got.etype != etBool {
153-
return 0, ErrBadArgumentStr{"string", got.etype.String()}
152+
if got.etype == etBool {
153+
*v.val = got.bool
154+
break
155+
}
156+
if got.etype == etString {
157+
if val, ok := strToBool(got.str); ok {
158+
*v.val = val
159+
break
160+
}
154161
}
155-
*v.val = got.bool
162+
return 0, ErrBadArgumentStr{"boolean", got.etype.String()}
156163
case ArgStringsOrInts:
157164
// consume all args (if any) in args that will yield a string or int
158165
for ; len(e.args) > pos && (e.args[pos].etype == etString || e.args[pos].etype == etInt); pos++ {
@@ -271,10 +278,17 @@ func (e expr) consumeKwarg(key string, optArgs []Arg) error {
271278
}
272279
*v.val = got.str
273280
case ArgBool:
274-
if got.etype != etBool {
275-
return ErrBadKwarg{key, exp, got.etype}
281+
if got.etype == etBool {
282+
*v.val = got.bool
283+
break
284+
}
285+
if got.etype == etString {
286+
if val, ok := strToBool(got.str); ok {
287+
*v.val = val
288+
break
289+
}
276290
}
277-
*v.val = got.bool
291+
return ErrBadKwarg{key, exp, got.etype}
278292
default:
279293
return fmt.Errorf("unsupported type %T for consumeKwarg", exp)
280294
}

expr/parse.go

+19-6
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,13 @@ func Parse(e string) (*expr, string, error) {
112112
return parseConst(e)
113113
}
114114

115-
if strings.HasPrefix(e, "True") || strings.HasPrefix(e, "true") {
116-
return &expr{bool: true, str: e[:4], etype: etBool}, e[4:], nil
117-
}
118-
119-
if strings.HasPrefix(e, "False") || strings.HasPrefix(e, "false") {
120-
return &expr{bool: false, str: e[:5], etype: etBool}, e[5:], nil
115+
if val, ok := strToBool(e); ok {
116+
// 'false' is 5 chars, 'true' is 4
117+
size := 5
118+
if val {
119+
size = 4
120+
}
121+
return &expr{bool: val, str: e[:size], etype: etBool}, e[size:], nil
121122
}
122123

123124
if e[0] == '\'' || e[0] == '"' {
@@ -151,6 +152,18 @@ func Parse(e string) (*expr, string, error) {
151152
return &expr{str: name, etype: etName}, e, nil
152153
}
153154

155+
func strToBool(val string) (bool, bool) {
156+
if strings.HasPrefix(val, "True") || strings.HasPrefix(val, "true") {
157+
return true, true
158+
}
159+
160+
if strings.HasPrefix(val, "False") || strings.HasPrefix(val, "false") {
161+
return false, true
162+
}
163+
164+
return false, false
165+
}
166+
154167
// caller must assure s starts with opening paren
155168
func parseArgList(e string) (string, []*expr, map[string]*expr, string, error) {
156169

expr/parse_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,22 @@ func TestParse(t *testing.T) {
325325
},
326326
nil,
327327
},
328+
{
329+
"func(metric, key2='true', key1='false')",
330+
&expr{
331+
str: "func",
332+
etype: etFunc,
333+
args: []*expr{
334+
{str: "metric"},
335+
},
336+
namedArgs: map[string]*expr{
337+
"key2": {etype: etString, str: "true"},
338+
"key1": {etype: etString, str: "false"},
339+
},
340+
argsStr: "metric, key2='true', key1='false'",
341+
},
342+
nil,
343+
},
328344

329345
{
330346
`foo.{bar,baz}.qux`,

expr/plan_test.go

+29
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ func TestArgs(t *testing.T) {
4848
},
4949
nil,
5050
},
51+
{
52+
"2 args normal, 2 optional by position (bools as strings)",
53+
[]*expr{
54+
{etype: etName, str: "foo.bar.*"},
55+
{etype: etString, str: "1hour"},
56+
{etype: etString, str: "sum"},
57+
{etype: etString, str: "false"},
58+
},
59+
nil,
60+
[]Req{
61+
NewReq("foo.bar.*", from, to, 0),
62+
},
63+
nil,
64+
},
5165
{
5266
"2 args normal, 2 optional by key",
5367
[]*expr{
@@ -63,6 +77,21 @@ func TestArgs(t *testing.T) {
6377
},
6478
nil,
6579
},
80+
{
81+
"2 args normal, 2 optional by key (bools as strings)",
82+
[]*expr{
83+
{etype: etName, str: "foo.bar.*"},
84+
{etype: etString, str: "1hour"},
85+
},
86+
map[string]*expr{
87+
"func": {etype: etString, str: "sum"},
88+
"alignToFrom": {etype: etString, str: "true"},
89+
},
90+
[]Req{
91+
NewReq("foo.bar.*", from, to, 0),
92+
},
93+
nil,
94+
},
6695
{
6796
"2 args normal, 1 by position, 1 by keyword",
6897
[]*expr{

0 commit comments

Comments
 (0)