-
-
Notifications
You must be signed in to change notification settings - Fork 201
/
behavior.go
171 lines (147 loc) · 3.81 KB
/
behavior.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package perm
import (
"encoding/json"
"fmt"
"reflect"
"github.com/webx-top/echo"
"github.com/webx-top/echo/param"
)
type Behavior struct {
Name string `json:",omitempty" xml:",omitempty"`
ValueType string `json:",omitempty" xml:",omitempty"` // list / number / json
VTypeOptions echo.H `json:",omitempty" xml:",omitempty"`
Value interface{} `json:",omitempty" xml:",omitempty"` // 在Behaviors中登记时,代表默认值;在BehaviorPerms中登记时代表针对某个用户设置的值
FormHelpBlock interface{}
valueInitor func() interface{}
formValueDecoder func([]string) (interface{}, error)
formValueEncoder func(interface{}) (string, error)
}
func (b Behavior) IsValid() bool {
return len(b.Name) > 0
}
func (b *Behavior) SetValueInitor(initor func() interface{}) {
b.valueInitor = initor
}
func (b *Behavior) SetFormValueDecoder(parser func([]string) (interface{}, error)) {
b.formValueDecoder = parser
}
func (b *Behavior) SetFormValueEncoder(encoder func(interface{}) (string, error)) {
b.formValueEncoder = encoder
}
func (b *Behavior) SetFormHelpBlock(helpBlock interface{}) {
b.FormHelpBlock = helpBlock
}
func (b *Behavior) String() string {
return b.AsString(b.Value)
}
func (b *Behavior) AsString(value interface{}) string {
if b.formValueEncoder != nil {
r, err := b.formValueEncoder(value)
if err != nil {
r = err.Error()
}
return r
}
switch b.ValueType {
case `json`, `slice`:
_b, err := json.Marshal(value)
if err != nil {
return err.Error()
}
return string(_b)
default:
v := reflect.Indirect(reflect.ValueOf(value))
switch v.Kind() {
case reflect.Slice, reflect.Map, reflect.Struct, reflect.Array:
_b, err := json.Marshal(value)
if err != nil {
return err.Error()
}
return string(_b)
default:
return param.AsString(value)
}
}
}
type BehaviorOption func(*Behavior)
func BehaviorOptName(name string) BehaviorOption {
return func(a *Behavior) {
a.Name = name
}
}
func BehaviorOptValueInitor(initor func() interface{}) BehaviorOption {
return func(a *Behavior) {
a.valueInitor = initor
}
}
func BehaviorOptFormValueDecoder(parser func([]string) (interface{}, error)) BehaviorOption {
return func(a *Behavior) {
a.formValueDecoder = parser
}
}
func BehaviorOptFormValueEncoder(encoder func(interface{}) (string, error)) BehaviorOption {
return func(a *Behavior) {
a.formValueEncoder = encoder
}
}
func BehaviorOptFormHelpBlock(helpBlock interface{}) BehaviorOption {
return func(a *Behavior) {
a.FormHelpBlock = helpBlock
}
}
func BehaviorOptValueType(vt string) BehaviorOption {
return func(a *Behavior) {
a.ValueType = vt
}
}
func BehaviorOptValue(defaultValue interface{}) BehaviorOption {
return func(a *Behavior) {
a.Value = defaultValue
}
}
func BehaviorOptVTypeOptions(opts echo.H) BehaviorOption {
return func(a *Behavior) {
a.VTypeOptions = opts
}
}
func BehaviorOptVTypeOption(key string, value interface{}) BehaviorOption {
return func(a *Behavior) {
if a.VTypeOptions == nil {
a.VTypeOptions = echo.H{}
}
a.VTypeOptions.Set(key, value)
}
}
func NewBehavior(opts ...BehaviorOption) *Behavior {
a := &Behavior{}
for _, option := range opts {
option(a)
}
return a
}
type Behaviors struct {
*echo.KVData
}
func NewBehaviors() *Behaviors {
return &Behaviors{
KVData: echo.NewKVData(),
}
}
func (m *Behaviors) Register(key string, value string, options ...interface{}) {
aOpts := []BehaviorOption{}
kOpts := []echo.KVOption{}
for _, o := range options {
switch v := o.(type) {
case BehaviorOption:
aOpts = append(aOpts, v)
case echo.KVOption:
kOpts = append(kOpts, v)
default:
panic(fmt.Sprintf(`unsupported type: %T`, v))
}
}
a := NewBehavior(aOpts...)
a.Name = key
kOpts = append(kOpts, echo.KVOptX(a))
m.Add(key, value, kOpts...)
}