-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetter.go
More file actions
82 lines (74 loc) · 1.74 KB
/
setter.go
File metadata and controls
82 lines (74 loc) · 1.74 KB
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
package loader
import (
"encoding"
"reflect"
)
// Setter is implemented by types can self-deserialize values.
// Any type that implements flag.Value also implements Setter.
type Setter interface {
Set(value string) error
}
type SetterFunc func(value string) error
func (f SetterFunc) Set(value string) error {
return f(value)
}
// getSetters return all eligible setter instances
func getSetters(field reflect.Value) []Setter {
var setters []Setter
if r := isSetter(field); r != nil {
setters = append(setters, r)
}
if t := isTextUnmarshaler(field); t != nil {
setters = append(setters, SetterFunc(func(value string) error {
return t.UnmarshalText([]byte(value))
}))
}
if b := isBinaryUnmarshaler(field); b != nil {
setters = append(setters, SetterFunc(func(value string) error {
return b.UnmarshalBinary([]byte(value))
}))
}
return setters
}
func isSetter(field reflect.Value) Setter {
if !field.CanInterface() {
return nil
}
v := field.Interface()
r, ok := v.(Setter)
if !ok && field.CanAddr() {
v := field.Addr().Interface()
if r, ok = v.(Setter); !ok {
return nil
}
}
return r
}
func isTextUnmarshaler(field reflect.Value) encoding.TextUnmarshaler {
if !field.CanInterface() {
return nil
}
v := field.Interface()
t, ok := v.(encoding.TextUnmarshaler)
if !ok && field.CanAddr() {
v := field.Addr().Interface()
if t, ok = v.(encoding.TextUnmarshaler); !ok {
return nil
}
}
return t
}
func isBinaryUnmarshaler(field reflect.Value) encoding.BinaryUnmarshaler {
if !field.CanInterface() {
return nil
}
v := field.Interface()
b, ok := v.(encoding.BinaryUnmarshaler)
if !ok && field.CanAddr() {
v := field.Addr().Interface()
if b, ok = v.(encoding.BinaryUnmarshaler); !ok {
return nil
}
}
return b
}