-
Notifications
You must be signed in to change notification settings - Fork 0
/
booleanfield.go
112 lines (99 loc) · 3.13 KB
/
booleanfield.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package aform
import (
"fmt"
)
// BooleanField is a field type that validates that the given value is a valid
// boolean.
type BooleanField struct {
initialValue string
*Field
}
// verify interface compliance
var _ fieldInterface = (*BooleanField)(nil)
// NewBooleanField creates a boolean field named name. The parameter initial is
// the initial value before data bounding. The default Widget is CheckboxInput.
// To change it, use WithWidget or SetWidget.
func NewBooleanField(name string, initial bool, opts ...FieldOption) (*BooleanField, error) {
cf := &BooleanField{
boolToValue(initial),
&Field{
name: name,
boundValues: []string{boolToValue(initial)},
errors: []Error{},
fieldType: BooleanFieldType,
widget: CheckboxInput,
autoID: defaultAutoID,
label: name,
labelSuffix: defaultLabelSuffix,
validateFunc: booleanFieldValidation,
locale: defaultLanguage,
},
}
for _, opt := range opts {
if err := opt(cf.Field); err != nil {
return nil, err
}
}
return cf, nil
}
// DefaultBooleanField creates a boolean field with reasonable default values.
// The initial parameter value is false.
func DefaultBooleanField(name string, opts ...FieldOption) (*BooleanField, error) {
return NewBooleanField(name, false, opts...)
}
func (fld *BooleanField) field() *Field {
return fld.Field
}
// Clean returns the cleaned value. value is first sanitized and
// finally validated. Sanitization can be customized with
// Field.SetSanitizeFunc. Validation can be customized with
// Field.SetValidateFunc.
func (fld *BooleanField) Clean(value string) (string, []Error) {
fld.boundValues = []string{value}
sanitizedValue := fld.sanitize(value)
if fld.notRequired && len(sanitizedValue) == 0 {
return fld.EmptyValue(), nil
}
fld.errors = customizeErrors(fld.validateFunc(sanitizedValue, !fld.notRequired), fld.customErrors)
return sanitizedValue, fld.errors
}
// EmptyValue returns the BooleanField empty value. The empty value is the
// cleaned value returned by Clean when there is no data bound to the field.
// A BooleanField empty value is always "off".
func (fld *BooleanField) EmptyValue() string {
return boolToValue(false)
}
// MustBoolean returns the clean value type cast to bool. It panics
// if the value provided is not a valid boolean input.
func (fld *BooleanField) MustBoolean(value string) bool {
v, errs := fld.Clean(value)
if len(errs) > 0 {
panic(fmt.Sprintf("MustBoolean called on %s field with an invalid boolean value: %s", fld.name, v))
}
return valueToBool(v)
}
func booleanFieldValidation(value string, required bool) []Error {
return validateValue(value, buildValidationRules(required, BooleanErrorCode))
}
func boolToValue(b bool) string {
if b {
return "on"
}
return "off"
}
func parseBool(v string) (bool, error) {
switch v {
case "1", "t", "T", "true", "TRUE", "True", "on", "ON", "On":
return true, nil
case "0", "f", "F", "false", "FALSE", "False", "off", "OFF", "Off":
return false, nil
}
return false, fmt.Errorf("not a bool %s", v)
}
func valueToBool(v string) bool {
b, err := parseBool(v)
if err != nil {
return false
}
return b
}