-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
slice.go
58 lines (45 loc) · 1.37 KB
/
slice.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
package validation
import "fmt"
// SliceType is a type constraint that accepts any slice type.
type SliceType[T any] interface {
~[]T
}
// SliceError describes a slice field validation error.
type SliceError[T any, V SliceType[T]] struct{ *FieldError[V] }
// Slice returns a new slice validation error.
func Slice[T any, V SliceType[T]](field string, value V) *SliceError[T, V] {
return &SliceError[T, V]{Field(field, value)}
}
// NotEmpty adds an error if the slice is empty.
func (e *SliceError[T, V]) NotEmpty() *SliceError[T, V] {
e.Func(NotEmptySlice)
return e
}
// Length adds an error if the slice length is not in the given range.
func (e *SliceError[T, V]) Length(min, max int) *SliceError[T, V] {
e.Func(SliceLength[T, V](min, max))
return e
}
// NotEmptySlice accepts any slice and returns a message if the value is empty.
func NotEmptySlice[T any, V SliceType[T]](s V) string {
if len(s) == 0 {
return "must not be empty"
}
return ""
}
// SliceLength accepts any slice and returns a message if the length is not in the given range.
func SliceLength[T any, V SliceType[T]](min, max int) func(s V) string {
return func(s V) string {
n := len(s)
if min == max {
if n != min {
return fmt.Sprintf("must be %d elements", min)
}
return ""
}
if n < min || n > max {
return fmt.Sprintf("must be between %d and %d elements", min, max)
}
return ""
}
}