Skip to content

Commit 70c4e8b

Browse files
committed
refactor: split field label and field name map
1 parent b5109dd commit 70c4e8b

8 files changed

+88
-49
lines changed

data_source.go

+3-7
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ type ConfigValidationFace interface {
147147
//
148148
// func (u *User) Translates() map[string]string {
149149
// return MS{
150-
// "Name": "User name",
150+
// "Name": "Username",
151151
// }
152152
// }
153153
type FieldTranslatorFace interface {
@@ -316,20 +316,16 @@ func (d *StructData) parseRulesFromTag(v *Validation) {
316316
if fName == "" && gOpt.FieldTag != "" {
317317
fName = fv.Tag.Get(gOpt.FieldTag)
318318
}
319+
319320
// add pre field display name to fName
320321
if fName != "" {
321322
if preStrName != "" {
322323
if preFName, ok := fMap[preStrName]; ok {
323324
fName = preFName + "." + fName
324325
}
325326
}
326-
fMap[name] = fName
327-
}
328327

329-
// Load the outgofmt info to output the error message whether to use the native field of GO
330-
tagInfo := fv.Tag.Get(gOpt.OutGoFmt)
331-
if tagInfo != "" {
332-
fMap[gOpt.OutGoFmt] = tagInfo
328+
fMap[name] = fName
333329
}
334330

335331
// load custom error messages.

data_source_test.go

-21
Original file line numberDiff line numberDiff line change
@@ -203,24 +203,3 @@ func TestStructData_Create(t *testing.T) {
203203
is.True(ok)
204204
is.Equal("inhere", str)
205205
}
206-
207-
208-
func TestIssue_103(t *testing.T) {
209-
type Example struct {
210-
SomeID string `json:"some_id" validate:"required" outgofmt:"1"`
211-
}
212-
o := Example{}
213-
v := Struct(o)
214-
v.Validate()
215-
m:=v.Errors.All() // here we get something like {"SomeID": { /* ... */ }}
216-
assert.Contains(t, m, "SomeID")
217-
218-
type Example2 struct {
219-
SomeID string `json:"some_id" validate:"required" `
220-
}
221-
e2 := Example2{}
222-
v2 := Struct(e2)
223-
v2.Validate()
224-
err2 :=v2.Errors.String()
225-
assert.Contains(t, err2, "some_id")
226-
}

issues_test.go

+26
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,32 @@ func TestIssue_92(t *testing.T) {
497497
assert.True(t, ok)
498498
}
499499

500+
// https://github.com/gookit/validate/issues/103
501+
func TestIssue_103(t *testing.T) {
502+
type Example struct {
503+
SomeID string `validate:"required"`
504+
}
505+
506+
o := Example{}
507+
v := validate.Struct(o)
508+
v.Validate()
509+
// here we get something like {"SomeID": { /* ... */ }}
510+
m := v.Errors.All()
511+
// dump.Println(m)
512+
assert.Contains(t, m, "SomeID")
513+
514+
type Example2 struct {
515+
SomeID string `json:"some_id" validate:"required" `
516+
}
517+
518+
e2 := Example2{}
519+
v2 := validate.Struct(e2)
520+
v2.Validate()
521+
err2 := v2.Errors.String() // here we get something like {"some_id": { /* ... */ }}
522+
dump.Println(v2.Errors)
523+
assert.Contains(t, err2, "some_id")
524+
}
525+
500526
type Issue104A struct {
501527
ID int `json:"id" gorm:"primarykey" form:"id" validate:"int|required"`
502528
}

messages.go

+42-13
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,15 @@ func BuiltinMessages() map[string]string {
253253

254254
// Translator definition
255255
type Translator struct {
256-
// language string TODO
257-
// field map {"field name": "display name"}
256+
// field name for output as Errors key.
257+
// format: {"field": "output name"}
258258
fieldMap map[string]string
259-
// message data map
259+
// the field translate name in message.
260+
// format: {"field": "translate name"}
261+
labelMap map[string]string
262+
// the error message data map.
263+
// key allow:
264+
// TODO
260265
messages map[string]string
261266
}
262267

@@ -275,6 +280,7 @@ func (t *Translator) Reset() {
275280
}
276281

277282
t.messages = newMessages
283+
t.labelMap = make(map[string]string)
278284
t.fieldMap = make(map[string]string)
279285
}
280286

@@ -283,6 +289,11 @@ func (t *Translator) FieldMap() map[string]string {
283289
return t.fieldMap
284290
}
285291

292+
// LabelMap data get
293+
func (t *Translator) LabelMap() map[string]string {
294+
return t.labelMap
295+
}
296+
286297
// AddMessages data to translator
287298
func (t *Translator) AddMessages(data map[string]string) {
288299
for n, m := range data {
@@ -292,9 +303,15 @@ func (t *Translator) AddMessages(data map[string]string) {
292303

293304
// AddFieldMap config field data.
294305
// If you want to display in the field with the original field is not the same
295-
func (t *Translator) AddFieldMap(fieldMap map[string]string) {
306+
func (t *Translator) AddFieldMap(labels map[string]string) {
307+
t.AddLabelMap(labels)
308+
}
309+
310+
// AddLabelMap config field translate data map.
311+
// If you want to display in the field with the original field is not the same
312+
func (t *Translator) AddLabelMap(fieldMap map[string]string) {
296313
for name, showName := range fieldMap {
297-
t.fieldMap[name] = showName
314+
t.labelMap[name] = showName
298315
}
299316
}
300317

@@ -303,12 +320,26 @@ func (t *Translator) AddMessage(key, msg string) {
303320
t.messages[key] = msg
304321
}
305322

306-
// HasField name in the t.fieldMap
323+
// HasField name in the t.labelMap.
324+
// Deprecated
307325
func (t *Translator) HasField(field string) bool {
308-
_, ok := t.fieldMap[field]
326+
return t.HasLabel(field)
327+
}
328+
329+
// HasLabel name in the t.labelMap
330+
func (t *Translator) HasLabel(field string) bool {
331+
_, ok := t.labelMap[field]
309332
return ok
310333
}
311334

335+
// LabelName get in the t.labelMap
336+
func (t *Translator) LabelName(field string) string {
337+
if label, ok := t.labelMap[field]; ok {
338+
field = label
339+
}
340+
return field
341+
}
342+
312343
// FieldName get in the t.fieldMap
313344
func (t *Translator) FieldName(field string) string {
314345
if trName, ok := t.fieldMap[field]; ok {
@@ -335,7 +366,7 @@ func (t *Translator) Message(validator, field string, args ...interface{}) (msg
335366

336367
// not found, fallback - use default error message
337368
if errMsg == "" {
338-
return t.FieldName(field) + defaultErrMsg
369+
return t.LabelName(field) + defaultErrMsg
339370
}
340371
}
341372

@@ -349,7 +380,7 @@ func (t *Translator) format(errMsg, field string, args []interface{}) string {
349380
// fix: #111 argN maybe is a field name
350381
for i, arg := range args {
351382
if name, ok := arg.(string); ok {
352-
if trName, ok := t.fieldMap[name]; ok {
383+
if trName, ok := t.labelMap[name]; ok {
353384
args[i] = trName
354385
}
355386
}
@@ -365,10 +396,8 @@ func (t *Translator) format(errMsg, field string, args []interface{}) string {
365396
}
366397

367398
// get field display name.
368-
if _, ok := t.fieldMap[outgofmt]; !ok {
369-
if trName, ok := t.fieldMap[field]; ok {
370-
field = trName
371-
}
399+
if trName, ok := t.labelMap[field]; ok {
400+
field = trName
372401
}
373402

374403
if argLen > 0 {

messages_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ func TestTranslatorBasic(t *testing.T) {
5252

5353
assert.True(t, tr.HasMessage("min"))
5454
assert.False(t, tr.HasMessage("not-exists"))
55+
assert.False(t, tr.HasLabel("FIELD1"))
5556
assert.False(t, tr.HasField("FIELD1"))
5657

5758
tr.AddMessage("FIELD1.min", "{field} message1")

validate.go

+10-5
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,11 @@ type GlobalOption struct {
5353
FilterTag string
5454
// ValidateTag in the struct tags.
5555
ValidateTag string
56-
// FieldTag name in the struct tags. for define field translate. default: json
56+
// FieldTag name in the struct tags.
57+
// use for define output field name/translate fallback. default: json
5758
FieldTag string
58-
// LabelTag display name in the struct tags. for define field translate. default: label
59+
// LabelTag display name in the struct tags.
60+
// use for define field translate. default: label
5961
LabelTag string
6062
// MessageTag define error message for the field.
6163
MessageTag string
@@ -69,8 +71,12 @@ type GlobalOption struct {
6971
CheckDefault bool
7072
// CheckZero Whether validate the default zero value. (intX,uintX: 0, string: "")
7173
CheckZero bool
72-
// OutGoFmt Whether to output the native fields of go.
73-
OutGoFmt string
74+
// ErrKeyFmt
75+
//
76+
// allow:
77+
// - 0 use struct field name as key. (for compatible)
78+
// - 1 use FieldTag defined name as key.
79+
ErrKeyFmt int8
7480
}
7581

7682
// global options
@@ -104,7 +110,6 @@ func newGlobalOption() *GlobalOption {
104110
MessageTag: messageTag,
105111
// tag name in struct tags
106112
ValidateTag: validateTag,
107-
OutGoFmt: outgofmt,
108113
}
109114
}
110115

validation.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ const (
1717
filterError = "_filter"
1818
validateError = "_validate"
1919

20-
outgofmt = "outgofmt"
2120
// sniff Length, use for detect file mime type
2221
sniffLen = 512
2322
// 32 MB
@@ -332,6 +331,7 @@ func (v *Validation) AddError(field, validator, msg string) {
332331
v.hasError = true
333332
}
334333

334+
field = v.trans.FieldName(field)
335335
v.Errors.Add(field, validator, msg)
336336
}
337337

validation_test.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func (f UserForm) Messages() map[string]string {
190190
}
191191
}
192192

193-
// Translates you can custom field translates.
193+
// Translates you can be custom field translates.
194194
func (f UserForm) Translates() map[string]string {
195195
return MS{
196196
"Name": "User Name",
@@ -207,12 +207,15 @@ func TestStruct(t *testing.T) {
207207

208208
// check trans data
209209
is.True(v.Trans().HasField("Name"))
210-
is.True(v.Trans().HasField("Safe"))
210+
is.True(v.Trans().HasLabel("Safe"))
211211
is.True(v.Trans().HasMessage("Name.required"))
212+
212213
// test trans
213214
v.Trans().AddMessage("custom", "message0")
214215
is.True(v.Trans().HasMessage("custom"))
215216
is.Contains(v.Trans().FieldMap(), "Name")
217+
is.Contains(v.Trans().LabelMap(), "Name")
218+
is.Equal("Name", v.Trans().LabelName("Name"))
216219

217220
// validate
218221
v.StopOnError = false

0 commit comments

Comments
 (0)