/
arrays.go
154 lines (134 loc) 路 4.06 KB
/
arrays.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
package validation
import (
"fmt"
"net"
"net/url"
"reflect"
"time"
"github.com/System-Glitch/goyave/v3/helper"
"github.com/google/uuid"
)
// createArray create a slice of the same type as the given type.
func createArray(dataType string, length int) reflect.Value {
var arr reflect.Value
switch dataType {
case "string":
newArray := make([]string, 0, length)
arr = reflect.ValueOf(&newArray).Elem()
case "numeric":
newArray := make([]float64, 0, length)
arr = reflect.ValueOf(&newArray).Elem()
case "integer":
newArray := make([]int, 0, length)
arr = reflect.ValueOf(&newArray).Elem()
case "timezone":
newArray := make([]*time.Location, 0, length)
arr = reflect.ValueOf(&newArray).Elem()
case "ip", "ipv4", "ipv6":
newArray := make([]net.IP, 0, length)
arr = reflect.ValueOf(&newArray).Elem()
case "json":
newArray := make([]interface{}, 0, length)
arr = reflect.ValueOf(&newArray).Elem()
case "url":
newArray := make([]*url.URL, 0, length)
arr = reflect.ValueOf(&newArray).Elem()
case "uuid":
newArray := make([]uuid.UUID, 0, length)
arr = reflect.ValueOf(&newArray).Elem()
case "bool":
newArray := make([]bool, 0, length)
arr = reflect.ValueOf(&newArray).Elem()
case "date":
newArray := make([]time.Time, 0, length)
arr = reflect.ValueOf(&newArray).Elem()
}
return arr
}
func validateArray(field string, value interface{}, parameters []string, form map[string]interface{}) bool {
if GetFieldType(value) == "array" {
if len(parameters) == 0 {
return true
}
if parameters[0] == "array" {
panic("Cannot use array type for array validation. Use \">array\" instead")
}
if !validationRules[parameters[0]].IsType {
panic(fmt.Sprintf("Rule %s is not converting, cannot use it for array validation", parameters[0]))
}
list := reflect.ValueOf(value)
length := list.Len()
arr := createArray(parameters[0], length)
params := parameters[1:]
for i := 0; i < length; i++ {
val := list.Index(i).Interface()
tmpData := map[string]interface{}{field: val}
if !validationRules[parameters[0]].Function(field, val, params, tmpData) {
return false
}
arr.Set(reflect.Append(arr, reflect.ValueOf(tmpData[field])))
}
form[field] = arr.Interface()
return true
}
return false
}
func validateDistinct(field string, value interface{}, parameters []string, form map[string]interface{}) bool {
if GetFieldType(value) != "array" {
return false // Can't validate if not an array
}
found := []interface{}{}
list := reflect.ValueOf(value)
for i := 0; i < list.Len(); i++ {
v := list.Index(i).Interface()
if helper.Contains(found, v) {
return false
}
found = append(found, v)
}
return true
}
func checkInNumeric(parameters []string, value interface{}) bool {
for _, v := range parameters {
floatVal, _ := helper.ToFloat64(value)
other, err := helper.ToFloat64(v)
if err == nil && floatVal == other { // Compare only values of the same type
return true
}
}
return false
}
func validateIn(field string, value interface{}, parameters []string, form map[string]interface{}) bool {
switch GetFieldType(value) {
case "numeric":
return checkInNumeric(parameters, value)
case "string":
return helper.Contains(parameters, value)
}
// Don't check arrays and files
return false
}
func validateNotIn(field string, value interface{}, parameters []string, form map[string]interface{}) bool {
switch GetFieldType(value) {
case "numeric":
return !checkInNumeric(parameters, value)
case "string":
return !helper.ContainsStr(parameters, value.(string))
}
// Don't check arrays and files
return false
}
func validateInArray(field string, value interface{}, parameters []string, form map[string]interface{}) bool {
other, exists := form[parameters[0]]
if exists && GetFieldType(other) == "array" {
return helper.Contains(other, value)
}
return false
}
func validateNotInArray(field string, value interface{}, parameters []string, form map[string]interface{}) bool {
other, exists := form[parameters[0]]
if exists && GetFieldType(other) == "array" {
return !helper.Contains(other, value)
}
return false
}