podman

Форк
0
276 строк · 7.3 Кб
1
package validator
2

3
import (
4
	"bytes"
5
	"fmt"
6
	"reflect"
7
	"strings"
8

9
	ut "github.com/go-playground/universal-translator"
10
)
11

12
const (
13
	fieldErrMsg = "Key: '%s' Error:Field validation for '%s' failed on the '%s' tag"
14
)
15

16
// ValidationErrorsTranslations is the translation return type
17
type ValidationErrorsTranslations map[string]string
18

19
// InvalidValidationError describes an invalid argument passed to
20
// `Struct`, `StructExcept`, StructPartial` or `Field`
21
type InvalidValidationError struct {
22
	Type reflect.Type
23
}
24

25
// Error returns InvalidValidationError message
26
func (e *InvalidValidationError) Error() string {
27

28
	if e.Type == nil {
29
		return "validator: (nil)"
30
	}
31

32
	return "validator: (nil " + e.Type.String() + ")"
33
}
34

35
// ValidationErrors is an array of FieldError's
36
// for use in custom error messages post validation.
37
type ValidationErrors []FieldError
38

39
// Error is intended for use in development + debugging and not intended to be a production error message.
40
// It allows ValidationErrors to subscribe to the Error interface.
41
// All information to create an error message specific to your application is contained within
42
// the FieldError found within the ValidationErrors array
43
func (ve ValidationErrors) Error() string {
44

45
	buff := bytes.NewBufferString("")
46

47
	for i := 0; i < len(ve); i++ {
48

49
		buff.WriteString(ve[i].Error())
50
		buff.WriteString("\n")
51
	}
52

53
	return strings.TrimSpace(buff.String())
54
}
55

56
// Translate translates all of the ValidationErrors
57
func (ve ValidationErrors) Translate(ut ut.Translator) ValidationErrorsTranslations {
58

59
	trans := make(ValidationErrorsTranslations)
60

61
	var fe *fieldError
62

63
	for i := 0; i < len(ve); i++ {
64
		fe = ve[i].(*fieldError)
65

66
		// // in case an Anonymous struct was used, ensure that the key
67
		// // would be 'Username' instead of ".Username"
68
		// if len(fe.ns) > 0 && fe.ns[:1] == "." {
69
		// 	trans[fe.ns[1:]] = fe.Translate(ut)
70
		// 	continue
71
		// }
72

73
		trans[fe.ns] = fe.Translate(ut)
74
	}
75

76
	return trans
77
}
78

79
// FieldError contains all functions to get error details
80
type FieldError interface {
81

82
	// Tag returns the validation tag that failed. if the
83
	// validation was an alias, this will return the
84
	// alias name and not the underlying tag that failed.
85
	//
86
	// eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
87
	// will return "iscolor"
88
	Tag() string
89

90
	// ActualTag returns the validation tag that failed, even if an
91
	// alias the actual tag within the alias will be returned.
92
	// If an 'or' validation fails the entire or will be returned.
93
	//
94
	// eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
95
	// will return "hexcolor|rgb|rgba|hsl|hsla"
96
	ActualTag() string
97

98
	// Namespace returns the namespace for the field error, with the tag
99
	// name taking precedence over the field's actual name.
100
	//
101
	// eg. JSON name "User.fname"
102
	//
103
	// See StructNamespace() for a version that returns actual names.
104
	//
105
	// NOTE: this field can be blank when validating a single primitive field
106
	// using validate.Field(...) as there is no way to extract it's name
107
	Namespace() string
108

109
	// StructNamespace returns the namespace for the field error, with the field's
110
	// actual name.
111
	//
112
	// eq. "User.FirstName" see Namespace for comparison
113
	//
114
	// NOTE: this field can be blank when validating a single primitive field
115
	// using validate.Field(...) as there is no way to extract its name
116
	StructNamespace() string
117

118
	// Field returns the fields name with the tag name taking precedence over the
119
	// field's actual name.
120
	//
121
	// eq. JSON name "fname"
122
	// see StructField for comparison
123
	Field() string
124

125
	// StructField returns the field's actual name from the struct, when able to determine.
126
	//
127
	// eq.  "FirstName"
128
	// see Field for comparison
129
	StructField() string
130

131
	// Value returns the actual field's value in case needed for creating the error
132
	// message
133
	Value() interface{}
134

135
	// Param returns the param value, in string form for comparison; this will also
136
	// help with generating an error message
137
	Param() string
138

139
	// Kind returns the Field's reflect Kind
140
	//
141
	// eg. time.Time's kind is a struct
142
	Kind() reflect.Kind
143

144
	// Type returns the Field's reflect Type
145
	//
146
	// eg. time.Time's type is time.Time
147
	Type() reflect.Type
148

149
	// Translate returns the FieldError's translated error
150
	// from the provided 'ut.Translator' and registered 'TranslationFunc'
151
	//
152
	// NOTE: if no registered translator can be found it returns the same as
153
	// calling fe.Error()
154
	Translate(ut ut.Translator) string
155

156
	// Error returns the FieldError's message
157
	Error() string
158
}
159

160
// compile time interface checks
161
var _ FieldError = new(fieldError)
162
var _ error = new(fieldError)
163

164
// fieldError contains a single field's validation error along
165
// with other properties that may be needed for error message creation
166
// it complies with the FieldError interface
167
type fieldError struct {
168
	v              *Validate
169
	tag            string
170
	actualTag      string
171
	ns             string
172
	structNs       string
173
	fieldLen       uint8
174
	structfieldLen uint8
175
	value          interface{}
176
	param          string
177
	kind           reflect.Kind
178
	typ            reflect.Type
179
}
180

181
// Tag returns the validation tag that failed.
182
func (fe *fieldError) Tag() string {
183
	return fe.tag
184
}
185

186
// ActualTag returns the validation tag that failed, even if an
187
// alias the actual tag within the alias will be returned.
188
func (fe *fieldError) ActualTag() string {
189
	return fe.actualTag
190
}
191

192
// Namespace returns the namespace for the field error, with the tag
193
// name taking precedence over the field's actual name.
194
func (fe *fieldError) Namespace() string {
195
	return fe.ns
196
}
197

198
// StructNamespace returns the namespace for the field error, with the field's
199
// actual name.
200
func (fe *fieldError) StructNamespace() string {
201
	return fe.structNs
202
}
203

204
// Field returns the field's name with the tag name taking precedence over the
205
// field's actual name.
206
func (fe *fieldError) Field() string {
207

208
	return fe.ns[len(fe.ns)-int(fe.fieldLen):]
209
	// // return fe.field
210
	// fld := fe.ns[len(fe.ns)-int(fe.fieldLen):]
211

212
	// log.Println("FLD:", fld)
213

214
	// if len(fld) > 0 && fld[:1] == "." {
215
	// 	return fld[1:]
216
	// }
217

218
	// return fld
219
}
220

221
// StructField returns the field's actual name from the struct, when able to determine.
222
func (fe *fieldError) StructField() string {
223
	// return fe.structField
224
	return fe.structNs[len(fe.structNs)-int(fe.structfieldLen):]
225
}
226

227
// Value returns the actual field's value in case needed for creating the error
228
// message
229
func (fe *fieldError) Value() interface{} {
230
	return fe.value
231
}
232

233
// Param returns the param value, in string form for comparison; this will
234
// also help with generating an error message
235
func (fe *fieldError) Param() string {
236
	return fe.param
237
}
238

239
// Kind returns the Field's reflect Kind
240
func (fe *fieldError) Kind() reflect.Kind {
241
	return fe.kind
242
}
243

244
// Type returns the Field's reflect Type
245
func (fe *fieldError) Type() reflect.Type {
246
	return fe.typ
247
}
248

249
// Error returns the fieldError's error message
250
func (fe *fieldError) Error() string {
251
	return fmt.Sprintf(fieldErrMsg, fe.ns, fe.Field(), fe.tag)
252
}
253

254
// Translate returns the FieldError's translated error
255
// from the provided 'ut.Translator' and registered 'TranslationFunc'
256
//
257
// NOTE: if no registered translation can be found, it returns the original
258
// untranslated error message.
259
func (fe *fieldError) Translate(ut ut.Translator) string {
260
	var fn TranslationFunc
261

262
	m, ok := fe.v.transTagFunc[ut]
263
	if !ok {
264
		return fe.Error()
265
	}
266

267
	fn, ok = m[fe.tag]
268
	if !ok {
269
		fn, ok = m[fe.actualTag]
270
		if !ok {
271
			return fe.Error()
272
		}
273
	}
274

275
	return fn(ut, fe)
276
}
277

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.