Skip to content

Commit 4816d06

Browse files
committed
revel#835 Atob and ToBool methods added
1 parent be4c74c commit 4816d06

File tree

4 files changed

+100
-13
lines changed

4 files changed

+100
-13
lines changed

binder.go

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -140,19 +140,11 @@ var (
140140
},
141141
}
142142

143-
// Booleans support a couple different value formats:
144-
// "true" and "false"
145-
// "on" and "" (a checkbox)
146-
// "1" and "0" (why not)
143+
// Booleans support a various value formats,
144+
// refer `revel.Atob` method.
147145
BoolBinder = Binder{
148146
Bind: ValueBinder(func(val string, typ reflect.Type) reflect.Value {
149-
v := strings.TrimSpace(strings.ToLower(val))
150-
switch v {
151-
case "true", "on", "1":
152-
return reflect.ValueOf(true)
153-
}
154-
// Return false by default.
155-
return reflect.ValueOf(false)
147+
return reflect.ValueOf(Atob(val))
156148
}),
157149
Unbind: func(output map[string]string, name string, val interface{}) {
158150
output[name] = fmt.Sprintf("%t", val)

binder_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ var (
4747
"bool-on": {"on"},
4848
"bool-false": {"false"},
4949
"bool-0": {"0"},
50-
"bool-off": {""},
50+
"bool-0.0": {"0.0"},
51+
"bool-off": {"off"},
52+
"bool-f": {"f"},
5153
"date": {"1982-07-09"},
5254
"datetime": {"1982-07-09 21:30"},
5355
"customDate": {"07/09/1982"},
@@ -112,7 +114,9 @@ var binderTestCases = map[string]interface{}{
112114
"bool-on": true,
113115
"bool-false": false,
114116
"bool-0": false,
117+
"bool-0.0": false,
115118
"bool-off": false,
119+
"bool-f": false,
116120
"date": testDate,
117121
"datetime": testDatetime,
118122
"customDate": testDate,
@@ -144,7 +148,7 @@ var binderTestCases = map[string]interface{}{
144148
// The point of these is to ensure that invalid user input does not cause panics.
145149
"invalidInt": 0,
146150
"invalidInt2": 0,
147-
"invalidBool": false,
151+
"invalidBool": true,
148152
"invalidArr": []int{},
149153
"priv": A{},
150154
"int8-overflow": int8(0),

libs.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"crypto/sha1"
1010
"encoding/hex"
1111
"io"
12+
"reflect"
13+
"strings"
1214
)
1315

1416
// Sign a given string with the app-configured secret key.
@@ -31,3 +33,54 @@ func Sign(message string) string {
3133
func Verify(message, sig string) bool {
3234
return hmac.Equal([]byte(sig), []byte(Sign(message)))
3335
}
36+
37+
// ToBool method converts/assert value into true or false. Default is true.
38+
// When converting to boolean, the following values are considered FALSE:
39+
// - The integer value is 0 (zero)
40+
// - The float value 0.0 (zero)
41+
// - The complex value 0.0 (zero)
42+
// - For string value, please refer `revel.Atob` method
43+
// - An array, map, slice with zero elements
44+
// - Boolean value returned as-is
45+
// - "nil" value
46+
func ToBool(val interface{}) bool {
47+
if val == nil {
48+
return false
49+
}
50+
51+
v := reflect.ValueOf(val)
52+
switch v.Kind() {
53+
case reflect.Bool:
54+
return v.Bool()
55+
case reflect.String:
56+
return Atob(v.String())
57+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
58+
return v.Int() != 0
59+
case reflect.Float32, reflect.Float64:
60+
return v.Float() != 0.0
61+
case reflect.Complex64, reflect.Complex128:
62+
return v.Complex() != 0.0
63+
case reflect.Array, reflect.Map, reflect.Slice:
64+
return v.Len() != 0
65+
}
66+
67+
// Return true by default
68+
return true
69+
}
70+
71+
// Atob converts string into boolean. It is in-case sensitive
72+
// When converting to boolean, the following values are considered FALSE:
73+
// - The "" (empty) string
74+
// - The "false" string
75+
// - The "f" string
76+
// - The "off" string,
77+
// - The string "0" & "0.0"
78+
func Atob(v string) bool {
79+
switch strings.TrimSpace(strings.ToLower(v)) {
80+
case "", "false", "off", "f", "0", "0.0":
81+
return false
82+
}
83+
84+
// Return true by default
85+
return true
86+
}

libs_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
2+
// Revel Framework source code and usage is governed by a MIT style
3+
// license that can be found in the LICENSE file.
4+
5+
package revel
6+
7+
import "testing"
8+
9+
func TestToBooleanForFalse(t *testing.T) {
10+
if ToBool(nil) ||
11+
ToBool([]string{}) ||
12+
ToBool(map[string]string{}) ||
13+
ToBool(0) ||
14+
ToBool(0.0) ||
15+
ToBool("") ||
16+
ToBool("false") ||
17+
ToBool("0") ||
18+
ToBool("0.0") ||
19+
ToBool("off") ||
20+
ToBool("f") {
21+
t.Error("Expected 'false' got 'true'")
22+
}
23+
}
24+
25+
func TestToBooleanForTrue(t *testing.T) {
26+
if !ToBool([]string{"true"}) ||
27+
!ToBool(map[string]string{"true": "value"}) ||
28+
!ToBool(1) ||
29+
!ToBool(0.1) ||
30+
!ToBool("not empty") ||
31+
!ToBool("true") ||
32+
!ToBool("1") ||
33+
!ToBool("1.0") ||
34+
!ToBool("on") ||
35+
!ToBool("t") {
36+
t.Error("Expected 'true' got 'false'")
37+
}
38+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy