-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalidaktor.go
81 lines (65 loc) · 1.53 KB
/
validaktor.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
package validaktor
import (
"fmt"
"reflect"
"strings"
)
const (
tagName = "validate"
)
type (
validator interface {
validate(interface{}) (bool, error)
applyValidatorOptions(...string) error
}
validaktor struct {
v map[string]validator
}
)
func NewValidaktor() *validaktor {
return &validaktor{v: validators()}
}
func (vldk *validaktor) getValidator(tag string) (validator, error) {
tags := strings.Split(tag, ",")
if len(tags) < 1 {
return nil, fmt.Errorf("validate: tags structure is not correct")
}
if v, ok := vldk.v[tags[0]]; !ok {
return nil, fmt.Errorf("validator not found")
} else {
return v, nil
}
}
func (vldk *validaktor) ValidateData(s interface{}) []error {
var errs []error
v := reflect.ValueOf(s)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
for i := 0; i < v.NumField(); i++ {
tag := v.Type().Field(i).Tag.Get(tagName)
if tag == "" || tag == "-" {
continue
}
data := strings.Split(tag, ",")
if len(data) != 2 {
errs = append(errs, fmt.Errorf("incorrect use of tag"))
return errs
}
tag = data[0]
args := data[1]
validator, err := vldk.getValidator(tag)
if err != nil {
errs = append(errs, fmt.Errorf("validate: %w", err))
return errs
}
if err := validator.applyValidatorOptions(args); err != nil {
errs = append(errs, fmt.Errorf("validate: %w", err))
return errs
}
if _, err := validator.validate(v.Field(i).Interface()); err != nil {
errs = append(errs, fmt.Errorf("validate: error in %s: %w", v.Type().Field(i).Name, err))
}
}
return errs
}