forked from ardanlabs/gotraining
-
Notifications
You must be signed in to change notification settings - Fork 0
/
example2.go
92 lines (76 loc) · 2.11 KB
/
example2.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
// All material is licensed under the Apache License Version 2.0, January 2004
// http://www.apache.org/licenses/LICENSE-2.0
// https://play.golang.org/p/fSMITKsv3p
/*
ValueOf returns a new Value initialized to the concrete value stored in the interface i.
ValueOf(nil) returns the zero Value.
func ValueOf(i interface{}) Value {
*/
// Sample program to show how to reflect on a struct type with tags.
package main
import (
"fmt"
"reflect"
"regexp"
)
// User is a sample struct.
type User struct {
Name string `valid:"exists"`
Email string `valid:"regexp" exp:"[\w.%+-]+@(?:[[:alnum:]-]+\\.)+[[:alpha:]]{2,6}"`
}
// Result provides a detail view of the validation results.
type Result struct {
Field string
Type string
Value string
Test string
Result bool
}
// main is the entry point for the application.
func main() {
// Declare a variable of type user.
user := User{
Name: "Henry Ford",
Email: "henry@ford.com",
}
// Validate the value and display the results.
results := validate(&user)
for _, result := range results {
fmt.Printf("%+v\n", result)
}
}
// validate performs data validation on any struct type value.
func validate(value interface{}) []Result {
// Declare a nil slice of Result values.
var results []Result
// Retrieve the value that the interface contains or points to.
val := reflect.ValueOf(value).Elem()
// Iterate over the fields of the struct value.
for i := 0; i < val.NumField(); i++ {
// Retrieve the field information.
typeField := val.Type().Field(i)
// Declare a variable of type Result and initialize
// it with all the meta-data.
result := Result{
Field: typeField.Name,
Type: typeField.Type.String(),
Value: val.Field(i).String(),
Test: typeField.Tag.Get("valid"),
}
// Perform the requested tests.
switch result.Test {
case "exists":
if result.Value != "" {
result.Result = true
}
case "regexp":
m, err := regexp.MatchString(typeField.Tag.Get("exp"), result.Value)
if err == nil && m == true {
result.Result = true
}
}
// Append the results to the slice.
results = append(results, result)
}
return results
}