From 956a5f59cfe09df5068ae0cfa57ca6ad2026d40a Mon Sep 17 00:00:00 2001 From: Vadim Petrov Date: Thu, 28 Dec 2017 19:19:18 +0300 Subject: [PATCH 1/5] Fix unused import of "fmt" package. Fix deep nested slices. --- examples/aliases/validators.go | 20 ++-- examples/complicated/entities.go | 2 + examples/complicated/validators.go | 146 ++++++++++++++++++----------- examples/empty/validators.go | 2 +- examples/overriding/validators.go | 2 +- examples/simple/validators.go | 16 ++-- main.go | 2 +- types/common.go | 36 +------ types/type_array.go | 16 +++- types/type_bool.go | 4 + types/type_byte.go | 4 + types/type_chan.go | 4 + types/type_custom.go | 4 + types/type_func.go | 4 + types/type_interface.go | 4 + types/type_map.go | 20 ++-- types/type_number.go | 4 + types/type_pointer.go | 4 + types/type_string.go | 4 + 19 files changed, 177 insertions(+), 121 deletions(-) diff --git a/examples/aliases/validators.go b/examples/aliases/validators.go index aeda6bf..eae784f 100644 --- a/examples/aliases/validators.go +++ b/examples/aliases/validators.go @@ -1,4 +1,4 @@ -//This file was automatically generated by the genval generator v1.4 +//This file was automatically generated by the genval generator v1.5 //Please don't modify it manually. Edit your entity tags and then //run go generate @@ -72,17 +72,17 @@ func (r User) Validate() error { if len(r.SomeMap) < 2 { errs.AddFieldf("SomeMap", "less items than 2") } - for SomeMapKey, SomeMapValue := range r.SomeMap { - _ = SomeMapKey - _ = SomeMapValue - if utf8.RuneCountInString(string(SomeMapKey)) > 64 { - errs.AddFieldf(fmt.Sprintf("SomeMap"+".%v", SomeMapKey), "longer than 64 chars") + for kSomeMap, vSomeMap := range r.SomeMap { + _ = kSomeMap + _ = vSomeMap + if utf8.RuneCountInString(string(kSomeMap)) > 64 { + errs.AddFieldf(fmt.Sprintf("SomeMap"+".%v", kSomeMap), "longer than 64 chars") } - if SomeMapValue < -35 { - errs.AddFieldf(fmt.Sprintf("SomeMap"+".%v", SomeMapKey), "less than -35") + if vSomeMap < -35 { + errs.AddFieldf(fmt.Sprintf("SomeMap"+".%v", vSomeMap), "less than -35") } - if SomeMapValue > 34 { - errs.AddFieldf(fmt.Sprintf("SomeMap"+".%v", SomeMapKey), "more than 34") + if vSomeMap > 34 { + errs.AddFieldf(fmt.Sprintf("SomeMap"+".%v", vSomeMap), "more than 34") } } if r.SomePointer == nil { diff --git a/examples/complicated/entities.go b/examples/complicated/entities.go index de48e71..b654817 100644 --- a/examples/complicated/entities.go +++ b/examples/complicated/entities.go @@ -31,6 +31,8 @@ type User struct { AliasOnAlias AliasOnDogsMapAlias AliasOnAliasWithCustomValidate AliasOnDogsMapAlias `validate:"func=.ValidateAlias"` MapOfMap map[string]map[int]string `validate:"value=[min_items=1,value=[min_len=3]]"` + MapOfSlice map[string][]string `validate:"value=[min_items=1,item=[max_len=256]]"` + SliceOfSliceOfSlice [][][]string `validate:"min_items=1,item=[min_items=1,item=[min_items=1,item=[max_len=256]]]"` FuncField func(int) string ChanField <-chan int ByteField byte diff --git a/examples/complicated/validators.go b/examples/complicated/validators.go index d463f7e..d4f4e73 100644 --- a/examples/complicated/validators.go +++ b/examples/complicated/validators.go @@ -1,4 +1,4 @@ -//This file was automatically generated by the genval generator v1.4 +//This file was automatically generated by the genval generator v1.5 //Please don't modify it manually. Edit your entity tags and then //run go generate @@ -46,11 +46,11 @@ func (r Dog) Validate() error { // Validate validates DogsMapAlias func (r DogsMapAlias) Validate() error { var errs errlist.List - for rKey, rValue := range r { - _ = rKey - _ = rValue - if err := rValue.Validate(); err != nil { - errs.AddField(fmt.Sprintf("r"+".%v", rKey), err) + for kr, vr := range r { + _ = kr + _ = vr + if err := vr.Validate(); err != nil { + errs.AddField(fmt.Sprintf("r"+".%v", vr), err) } } return errs.ErrorOrNil() @@ -122,22 +122,22 @@ func (r User) Validate() error { if len(r.Urls) < 1 { errs.AddFieldf("Urls", "less items than 1") } - for i, x := range r.Urls { - _ = i - _ = x - if utf8.RuneCountInString(string(x)) > 256 { - errs.AddFieldf(fmt.Sprintf("Urls.%v", i), "longer than 256 chars") + for kUrls, vUrls := range r.Urls { + _ = kUrls + _ = vUrls + if utf8.RuneCountInString(string(vUrls)) > 256 { + errs.AddFieldf(fmt.Sprintf("Urls"+".%v", kUrls), "longer than 256 chars") } } if len(r.Dogs) < 1 { errs.AddFieldf("Dogs", "less items than 1") } - for i, x := range r.Dogs { - _ = i - _ = x - if x != nil { - if err := x.Validate(); err != nil { - errs.AddField(fmt.Sprintf("Dogs.%v", i), err) + for kDogs, vDogs := range r.Dogs { + _ = kDogs + _ = vDogs + if vDogs != nil { + if err := vDogs.Validate(); err != nil { + errs.AddField(fmt.Sprintf("Dogs"+".%v", kDogs), err) } } } @@ -145,11 +145,11 @@ func (r User) Validate() error { if len(*r.Test) < 1 { errs.AddFieldf("Test", "less items than 1") } - for i, x := range *r.Test { - _ = i - _ = x - if x < 4 { - errs.AddFieldf(fmt.Sprintf("Test.%v", i), "less than 4") + for kTest, vTest := range *r.Test { + _ = kTest + _ = vTest + if vTest < 4 { + errs.AddFieldf(fmt.Sprintf("Test"+".%v", kTest), "less than 4") } } } @@ -159,37 +159,37 @@ func (r User) Validate() error { if len(r.SomeArray) < 1 { errs.AddFieldf("SomeArray", "less items than 1") } - for i, x := range r.SomeArray { - _ = i - _ = x - if err := validateSome(x); err != nil { - errs.AddField(fmt.Sprintf("SomeArray.%v", i), err) + for kSomeArray, vSomeArray := range r.SomeArray { + _ = kSomeArray + _ = vSomeArray + if err := validateSome(vSomeArray); err != nil { + errs.AddField(fmt.Sprintf("SomeArray"+".%v", kSomeArray), err) } } if len(r.Dict) < 2 { errs.AddFieldf("Dict", "less items than 2") } - for DictKey, DictValue := range r.Dict { - _ = DictKey - _ = DictValue - if utf8.RuneCountInString(string(DictKey)) > 64 { - errs.AddFieldf(fmt.Sprintf("Dict"+".%v", DictKey), "longer than 64 chars") + for kDict, vDict := range r.Dict { + _ = kDict + _ = vDict + if utf8.RuneCountInString(string(kDict)) > 64 { + errs.AddFieldf(fmt.Sprintf("Dict"+".%v", kDict), "longer than 64 chars") } - if DictValue < -35 { - errs.AddFieldf(fmt.Sprintf("Dict"+".%v", DictKey), "less than -35") + if vDict < -35 { + errs.AddFieldf(fmt.Sprintf("Dict"+".%v", vDict), "less than -35") } - if DictValue > 34 { - errs.AddFieldf(fmt.Sprintf("Dict"+".%v", DictKey), "more than 34") + if vDict > 34 { + errs.AddFieldf(fmt.Sprintf("Dict"+".%v", vDict), "more than 34") } } - for DictDogsKey, DictDogsValue := range r.DictDogs { - _ = DictDogsKey - _ = DictDogsValue - if err := DictDogsValue.ValidateOptional(); err != nil { - errs.AddField(fmt.Sprintf("DictDogs"+".%v", DictDogsKey), err) + for kDictDogs, vDictDogs := range r.DictDogs { + _ = kDictDogs + _ = vDictDogs + if err := vDictDogs.ValidateOptional(); err != nil { + errs.AddField(fmt.Sprintf("DictDogs"+".%v", vDictDogs), err) } - if err := validateMaxDogName(DictDogsValue); err != nil { - errs.AddField(fmt.Sprintf("DictDogs"+".%v", DictDogsKey), err) + if err := validateMaxDogName(vDictDogs); err != nil { + errs.AddField(fmt.Sprintf("DictDogs"+".%v", vDictDogs), err) } } if err := r.Alias.Validate(); err != nil { @@ -201,17 +201,55 @@ func (r User) Validate() error { if err := r.AliasOnAliasWithCustomValidate.ValidateAlias(); err != nil { errs.AddField("AliasOnAliasWithCustomValidate", err) } - for MapOfMapKey, MapOfMapValue := range r.MapOfMap { - _ = MapOfMapKey - _ = MapOfMapValue - if len(MapOfMapValue) < 1 { - errs.AddFieldf(fmt.Sprintf("MapOfMap"+".%v", MapOfMapKey), "less items than 1") - } - for MapOfMapValueKey, MapOfMapValueValue := range MapOfMapValue { - _ = MapOfMapValueKey - _ = MapOfMapValueValue - if utf8.RuneCountInString(string(MapOfMapValueValue)) < 3 { - errs.AddFieldf(fmt.Sprintf(fmt.Sprintf("MapOfMap"+".%v", MapOfMapKey)+".%v", MapOfMapValueKey), "shorter than 3 chars") + for kMapOfMap, vMapOfMap := range r.MapOfMap { + _ = kMapOfMap + _ = vMapOfMap + if len(vMapOfMap) < 1 { + errs.AddFieldf(fmt.Sprintf("MapOfMap"+".%v", vMapOfMap), "less items than 1") + } + for kvMapOfMap, vvMapOfMap := range vMapOfMap { + _ = kvMapOfMap + _ = vvMapOfMap + if utf8.RuneCountInString(string(vvMapOfMap)) < 3 { + errs.AddFieldf(fmt.Sprintf(fmt.Sprintf("MapOfMap"+".%v", vMapOfMap)+".%v", vvMapOfMap), "shorter than 3 chars") + } + } + } + for kMapOfSlice, vMapOfSlice := range r.MapOfSlice { + _ = kMapOfSlice + _ = vMapOfSlice + if len(vMapOfSlice) < 1 { + errs.AddFieldf(fmt.Sprintf("MapOfSlice"+".%v", vMapOfSlice), "less items than 1") + } + for kvMapOfSlice, vvMapOfSlice := range vMapOfSlice { + _ = kvMapOfSlice + _ = vvMapOfSlice + if utf8.RuneCountInString(string(vvMapOfSlice)) > 256 { + errs.AddFieldf(fmt.Sprintf(fmt.Sprintf("MapOfSlice"+".%v", vMapOfSlice)+".%v", kvMapOfSlice), "longer than 256 chars") + } + } + } + if len(r.SliceOfSliceOfSlice) < 1 { + errs.AddFieldf("SliceOfSliceOfSlice", "less items than 1") + } + for kSliceOfSliceOfSlice, vSliceOfSliceOfSlice := range r.SliceOfSliceOfSlice { + _ = kSliceOfSliceOfSlice + _ = vSliceOfSliceOfSlice + if len(vSliceOfSliceOfSlice) < 1 { + errs.AddFieldf(fmt.Sprintf("SliceOfSliceOfSlice"+".%v", kSliceOfSliceOfSlice), "less items than 1") + } + for kvSliceOfSliceOfSlice, vvSliceOfSliceOfSlice := range vSliceOfSliceOfSlice { + _ = kvSliceOfSliceOfSlice + _ = vvSliceOfSliceOfSlice + if len(vvSliceOfSliceOfSlice) < 1 { + errs.AddFieldf(fmt.Sprintf(fmt.Sprintf("SliceOfSliceOfSlice"+".%v", kSliceOfSliceOfSlice)+".%v", kvSliceOfSliceOfSlice), "less items than 1") + } + for kvvSliceOfSliceOfSlice, vvvSliceOfSliceOfSlice := range vvSliceOfSliceOfSlice { + _ = kvvSliceOfSliceOfSlice + _ = vvvSliceOfSliceOfSlice + if utf8.RuneCountInString(string(vvvSliceOfSliceOfSlice)) > 256 { + errs.AddFieldf(fmt.Sprintf(fmt.Sprintf(fmt.Sprintf("SliceOfSliceOfSlice"+".%v", kSliceOfSliceOfSlice)+".%v", kvSliceOfSliceOfSlice)+".%v", kvvSliceOfSliceOfSlice), "longer than 256 chars") + } } } } diff --git a/examples/empty/validators.go b/examples/empty/validators.go index 7133804..9ee5d0c 100644 --- a/examples/empty/validators.go +++ b/examples/empty/validators.go @@ -1,4 +1,4 @@ -//This file was automatically generated by the genval generator v1.4 +//This file was automatically generated by the genval generator v1.5 //Please don't modify it manually. Edit your entity tags and then //run go generate diff --git a/examples/overriding/validators.go b/examples/overriding/validators.go index bdb259b..db6236a 100644 --- a/examples/overriding/validators.go +++ b/examples/overriding/validators.go @@ -1,4 +1,4 @@ -//This file was automatically generated by the genval generator v1.4 +//This file was automatically generated by the genval generator v1.5 //Please don't modify it manually. Edit your entity tags and then //run go generate diff --git a/examples/simple/validators.go b/examples/simple/validators.go index e17a5fa..c47d8b5 100644 --- a/examples/simple/validators.go +++ b/examples/simple/validators.go @@ -1,4 +1,4 @@ -//This file was automatically generated by the genval generator v1.4 +//This file was automatically generated by the genval generator v1.5 //Please don't modify it manually. Edit your entity tags and then //run go generate @@ -69,14 +69,14 @@ func (r User) Validate() error { if len(r.Emails) < 1 { errs.AddFieldf("Emails", "less items than 1") } - for EmailsKey, EmailsValue := range r.Emails { - _ = EmailsKey - _ = EmailsValue - if EmailsKey > 3 { - errs.AddFieldf(fmt.Sprintf("Emails"+".%v", EmailsKey), "more than 3") + for kEmails, vEmails := range r.Emails { + _ = kEmails + _ = vEmails + if kEmails > 3 { + errs.AddFieldf(fmt.Sprintf("Emails"+".%v", kEmails), "more than 3") } - if utf8.RuneCountInString(string(EmailsValue)) < 5 { - errs.AddFieldf(fmt.Sprintf("Emails"+".%v", EmailsKey), "shorter than 5 chars") + if utf8.RuneCountInString(string(vEmails)) < 5 { + errs.AddFieldf(fmt.Sprintf("Emails"+".%v", vEmails), "shorter than 5 chars") } } if r.Title == nil { diff --git a/main.go b/main.go index 06f0d7d..3cb70ee 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,7 @@ import ( ) const ( - version = "1.4" + version = "1.5" ) var ( diff --git a/types/common.go b/types/common.go index 6f91a4e..cab5de4 100644 --- a/types/common.go +++ b/types/common.go @@ -13,6 +13,7 @@ type TypeDef interface { Type() string SetValidateTag(ValidatableTag) error Validate() error + NeedGenerate() bool Generate(w io.Writer, cfg GenConfig, name Name) Expr() ast.Expr } @@ -68,18 +69,12 @@ func NewName(pointerPrefix, structVar, labelName, fieldName, tagName string) Nam } } -func NewIndexedName(labelName, indexVar, validateVar, tagName string, complexLabelName bool) Name { - - labelNamePrepared := fmt.Sprintf("fmt.Sprintf(\"%s.%%v\", %v)", labelName, indexVar) - if complexLabelName { - labelNamePrepared = fmt.Sprintf("fmt.Sprintf(%s + \".%%v\", %v)", labelName, indexVar) - } - +func NewIndexedName(labelName, indexVar, validateVar, tagName string) Name { return Name{ pointerPrefix: "", structVar: "", fieldName: validateVar, - labelName: labelNamePrepared, + labelName: fmt.Sprintf("fmt.Sprintf(%s + \".%%v\", %v)", labelName, indexVar), tagName: tagName, } } @@ -144,31 +139,6 @@ func parseFuncsParam(p string) []string { return res } -func needGenerate(t TypeDef) bool { - switch tpe := t.(type) { - case *typeByte: - return false - case *typeBool: - return false - case *typeNumber: - if validMaxMin(tpe.max, tpe.min) { - return true - } - return false - case *typeString: - if validMaxMin(tpe.maxLen, tpe.minLen) { - return true - } - return false - case *typeArray: - return needGenerate(tpe.innerType) || validMaxMin(tpe.max, tpe.min) - case *typeMap: - return needGenerate(tpe.key) || needGenerate(tpe.value) - default: - return true - } -} - func validMaxMin(max, min *string) bool { return max != nil || (min != nil && *min != "0") } diff --git a/types/type_array.go b/types/type_array.go index 5ee4a04..f639bfc 100644 --- a/types/type_array.go +++ b/types/type_array.go @@ -43,6 +43,10 @@ func (t *typeArray) SetValidateTag(tag ValidatableTag) error { return nil } +func (t typeArray) NeedGenerate() bool { + return t.innerType.NeedGenerate() || validMaxMin(t.max, t.min) +} + func (t typeArray) Generate(w io.Writer, cfg GenConfig, name Name) { if t.min != nil { if *t.min != "0" { @@ -57,12 +61,14 @@ func (t typeArray) Generate(w io.Writer, cfg GenConfig, name Name) { fmt.Fprintf(w, "}\n") } - if needGenerate(t.innerType) || validMaxMin(t.max, t.min) { - fmt.Fprintf(w, "for i, x := range %s {\n", name.Full()) - fmt.Fprintf(w, " _ = i \n") - fmt.Fprintf(w, " _ = x \n") + if t.innerType.NeedGenerate() { + kName := "k" + name.fieldName + vName := "v" + name.fieldName + fmt.Fprintf(w, "for %s, %s := range %s {\n", kName, vName, name.Full()) + fmt.Fprintf(w, " _ = %s \n", kName) + fmt.Fprintf(w, " _ = %s \n", vName) cfg.AddImport("fmt") - t.innerType.Generate(w, cfg, NewIndexedName(name.labelName[1:len(name.labelName)-1], "i", "x", name.tagName, false)) + t.innerType.Generate(w, cfg, NewIndexedName(name.labelName, kName, vName, name.tagName)) fmt.Fprintf(w, "}\n") } } diff --git a/types/type_bool.go b/types/type_bool.go index 0d6f525..2e7b3cc 100644 --- a/types/type_bool.go +++ b/types/type_bool.go @@ -22,6 +22,10 @@ func (t *typeBool) SetValidateTag(tag ValidatableTag) error { return ErrUnusedTag } +func (t typeBool) NeedGenerate() bool { + return false +} + func (t typeBool) Generate(w io.Writer, cfg GenConfig, name Name) { } diff --git a/types/type_byte.go b/types/type_byte.go index 174519a..a5c31ab 100644 --- a/types/type_byte.go +++ b/types/type_byte.go @@ -22,6 +22,10 @@ func (t *typeByte) SetValidateTag(tag ValidatableTag) error { return ErrUnusedTag } +func (t typeByte) NeedGenerate() bool { + return false +} + func (t typeByte) Generate(w io.Writer, cfg GenConfig, name Name) { } diff --git a/types/type_chan.go b/types/type_chan.go index 4fb754d..18fe2e5 100644 --- a/types/type_chan.go +++ b/types/type_chan.go @@ -20,6 +20,10 @@ func (t *typeChan) SetValidateTag(tag ValidatableTag) error { return ErrUnusedTag } +func (t typeChan) NeedGenerate() bool { + return false +} + func (t typeChan) Generate(w io.Writer, cfg GenConfig, name Name) { } diff --git a/types/type_custom.go b/types/type_custom.go index e74959c..5a6437b 100644 --- a/types/type_custom.go +++ b/types/type_custom.go @@ -41,6 +41,10 @@ func (t *typeCustom) SetValidateTag(tag ValidatableTag) error { return nil } +func (t typeCustom) NeedGenerate() bool { + return true +} + func (t typeCustom) Generate(w io.Writer, cfg GenConfig, name Name) { registerError := `errs.AddField(%s, err)` diff --git a/types/type_func.go b/types/type_func.go index 33ad565..5b1e5ae 100644 --- a/types/type_func.go +++ b/types/type_func.go @@ -20,6 +20,10 @@ func (t *typeFunc) SetValidateTag(tag ValidatableTag) error { return ErrUnusedTag } +func (t typeFunc) NeedGenerate() bool { + return false +} + func (t typeFunc) Generate(w io.Writer, cfg GenConfig, name Name) { } diff --git a/types/type_interface.go b/types/type_interface.go index ffd38c3..1309bd1 100644 --- a/types/type_interface.go +++ b/types/type_interface.go @@ -30,6 +30,10 @@ func (t *typeInterface) SetValidateTag(tag ValidatableTag) error { return nil } +func (t typeInterface) NeedGenerate() bool { + return len(t.funcs) > 0 +} + func (t typeInterface) Generate(w io.Writer, cfg GenConfig, name Name) { for _, f := range t.funcs { fmt.Fprintf(w, "if err := %s(%s); err != nil {\n", f, name.Full()) diff --git a/types/type_map.go b/types/type_map.go index 851a1cd..70c7398 100644 --- a/types/type_map.go +++ b/types/type_map.go @@ -51,6 +51,10 @@ func (t *typeMap) SetValidateTag(tag ValidatableTag) error { return nil } +func (t typeMap) NeedGenerate() bool { + return t.key.NeedGenerate() || t.value.NeedGenerate() || validMaxMin(t.max, t.min) +} + func (t typeMap) Generate(w io.Writer, cfg GenConfig, name Name) { if t.min != nil { if *t.min != "0" { @@ -65,15 +69,15 @@ func (t typeMap) Generate(w io.Writer, cfg GenConfig, name Name) { fmt.Fprintf(w, "}\n") } - if needGenerate(&t) { - keyVarName := genName(name.fieldName, true) - valVarName := genName(name.fieldName, false) - fmt.Fprintf(w, "for %s, %s := range %s {\n", keyVarName, valVarName, name.Full()) - fmt.Fprintf(w, " _ = %s \n", keyVarName) - fmt.Fprintf(w, " _ = %s \n", valVarName) + if t.key.NeedGenerate() || t.value.NeedGenerate() { + kName := "k" + name.fieldName + vName := "v" + name.fieldName + fmt.Fprintf(w, "for %s, %s := range %s {\n", kName, vName, name.Full()) + fmt.Fprintf(w, " _ = %s \n", kName) + fmt.Fprintf(w, " _ = %s \n", vName) cfg.AddImport("fmt") - t.key.Generate(w, cfg, NewIndexedName(name.LabelName(), keyVarName, keyVarName, name.tagName, true)) - t.value.Generate(w, cfg, NewIndexedName(name.LabelName(), keyVarName, valVarName, name.tagName, true)) + t.key.Generate(w, cfg, NewIndexedName(name.labelName, kName, kName, name.tagName)) + t.value.Generate(w, cfg, NewIndexedName(name.labelName, vName, vName, name.tagName)) fmt.Fprintf(w, "}\n") } } diff --git a/types/type_number.go b/types/type_number.go index 0b12104..d3b1815 100644 --- a/types/type_number.go +++ b/types/type_number.go @@ -33,6 +33,10 @@ func (t *typeNumber) SetValidateTag(tag ValidatableTag) error { return nil } +func (t typeNumber) NeedGenerate() bool { + return validMaxMin(t.max, t.min) +} + func (t typeNumber) Generate(w io.Writer, cfg GenConfig, name Name) { if t.min != nil { fmt.Fprintf(w, "if %s < %s {\n", name.Full(), *t.min) diff --git a/types/type_pointer.go b/types/type_pointer.go index 897fe2a..a0ed57c 100644 --- a/types/type_pointer.go +++ b/types/type_pointer.go @@ -39,6 +39,10 @@ func (t *TypePointer) SetValidateTag(tag ValidatableTag) error { return nil } +func (t TypePointer) NeedGenerate() bool { + return true +} + func (t *TypePointer) Generate(w io.Writer, cfg GenConfig, name Name) { if t.nullable { fmt.Fprintf(w, "if %s != nil {\n", name.Full()) diff --git a/types/type_string.go b/types/type_string.go index fcbf389..d765943 100644 --- a/types/type_string.go +++ b/types/type_string.go @@ -35,6 +35,10 @@ func (t *typeString) SetValidateTag(tag ValidatableTag) error { return nil } +func (t typeString) NeedGenerate() bool { + return validMaxMin(t.maxLen, t.minLen) +} + func (t typeString) Generate(w io.Writer, cfg GenConfig, name Name) { if t.minLen != nil { if *t.minLen != "0" { From cc630a9896ec25e2a5935001e4e43b39c8ed9e06 Mon Sep 17 00:00:00 2001 From: Vadim Petrov Date: Fri, 29 Dec 2017 11:25:32 +0300 Subject: [PATCH 2/5] Remove unnecessary nil assignments --- examples/aliases/validators.go | 8 ++-- examples/complicated/entities.go | 5 ++- examples/complicated/validators.go | 64 ++++++++++++------------------ examples/simple/validators.go | 6 +-- types/common.go | 13 +++++- types/type_array.go | 4 +- types/type_map.go | 18 +++++---- 7 files changed, 59 insertions(+), 59 deletions(-) diff --git a/examples/aliases/validators.go b/examples/aliases/validators.go index eae784f..8d8ffa3 100644 --- a/examples/aliases/validators.go +++ b/examples/aliases/validators.go @@ -73,16 +73,14 @@ func (r User) Validate() error { errs.AddFieldf("SomeMap", "less items than 2") } for kSomeMap, vSomeMap := range r.SomeMap { - _ = kSomeMap - _ = vSomeMap if utf8.RuneCountInString(string(kSomeMap)) > 64 { - errs.AddFieldf(fmt.Sprintf("SomeMap"+".%v", kSomeMap), "longer than 64 chars") + errs.AddFieldf(fmt.Sprintf("SomeMap"+".key[%v]", kSomeMap), "longer than 64 chars") } if vSomeMap < -35 { - errs.AddFieldf(fmt.Sprintf("SomeMap"+".%v", vSomeMap), "less than -35") + errs.AddFieldf(fmt.Sprintf("SomeMap"+".%v", kSomeMap), "less than -35") } if vSomeMap > 34 { - errs.AddFieldf(fmt.Sprintf("SomeMap"+".%v", vSomeMap), "more than 34") + errs.AddFieldf(fmt.Sprintf("SomeMap"+".%v", kSomeMap), "more than 34") } } if r.SomePointer == nil { diff --git a/examples/complicated/entities.go b/examples/complicated/entities.go index b654817..9019c7d 100644 --- a/examples/complicated/entities.go +++ b/examples/complicated/entities.go @@ -30,9 +30,12 @@ type User struct { Alias DogsMapAlias AliasOnAlias AliasOnDogsMapAlias AliasOnAliasWithCustomValidate AliasOnDogsMapAlias `validate:"func=.ValidateAlias"` - MapOfMap map[string]map[int]string `validate:"value=[min_items=1,value=[min_len=3]]"` + MapOfMap map[string]map[int]string `validate:"key=[min_len=3],value=[min_items=1,value=[min_len=3]]"` MapOfSlice map[string][]string `validate:"value=[min_items=1,item=[max_len=256]]"` + SliceOfMap []map[string]int `validate:"item=[min_items=1,key=[min_len=3],value=[min=1]]"` SliceOfSliceOfSlice [][][]string `validate:"min_items=1,item=[min_items=1,item=[min_items=1,item=[max_len=256]]]"` + MapWithoutValidation map[string]interface{} + SliceWithoutValidation []interface{} FuncField func(int) string ChanField <-chan int ByteField byte diff --git a/examples/complicated/validators.go b/examples/complicated/validators.go index d4f4e73..c828a36 100644 --- a/examples/complicated/validators.go +++ b/examples/complicated/validators.go @@ -47,10 +47,8 @@ func (r Dog) Validate() error { func (r DogsMapAlias) Validate() error { var errs errlist.List for kr, vr := range r { - _ = kr - _ = vr if err := vr.Validate(); err != nil { - errs.AddField(fmt.Sprintf("r"+".%v", vr), err) + errs.AddField(fmt.Sprintf("r"+".%v", kr), err) } } return errs.ErrorOrNil() @@ -123,8 +121,6 @@ func (r User) Validate() error { errs.AddFieldf("Urls", "less items than 1") } for kUrls, vUrls := range r.Urls { - _ = kUrls - _ = vUrls if utf8.RuneCountInString(string(vUrls)) > 256 { errs.AddFieldf(fmt.Sprintf("Urls"+".%v", kUrls), "longer than 256 chars") } @@ -133,8 +129,6 @@ func (r User) Validate() error { errs.AddFieldf("Dogs", "less items than 1") } for kDogs, vDogs := range r.Dogs { - _ = kDogs - _ = vDogs if vDogs != nil { if err := vDogs.Validate(); err != nil { errs.AddField(fmt.Sprintf("Dogs"+".%v", kDogs), err) @@ -146,8 +140,6 @@ func (r User) Validate() error { errs.AddFieldf("Test", "less items than 1") } for kTest, vTest := range *r.Test { - _ = kTest - _ = vTest if vTest < 4 { errs.AddFieldf(fmt.Sprintf("Test"+".%v", kTest), "less than 4") } @@ -160,8 +152,6 @@ func (r User) Validate() error { errs.AddFieldf("SomeArray", "less items than 1") } for kSomeArray, vSomeArray := range r.SomeArray { - _ = kSomeArray - _ = vSomeArray if err := validateSome(vSomeArray); err != nil { errs.AddField(fmt.Sprintf("SomeArray"+".%v", kSomeArray), err) } @@ -170,26 +160,22 @@ func (r User) Validate() error { errs.AddFieldf("Dict", "less items than 2") } for kDict, vDict := range r.Dict { - _ = kDict - _ = vDict if utf8.RuneCountInString(string(kDict)) > 64 { - errs.AddFieldf(fmt.Sprintf("Dict"+".%v", kDict), "longer than 64 chars") + errs.AddFieldf(fmt.Sprintf("Dict"+".key[%v]", kDict), "longer than 64 chars") } if vDict < -35 { - errs.AddFieldf(fmt.Sprintf("Dict"+".%v", vDict), "less than -35") + errs.AddFieldf(fmt.Sprintf("Dict"+".%v", kDict), "less than -35") } if vDict > 34 { - errs.AddFieldf(fmt.Sprintf("Dict"+".%v", vDict), "more than 34") + errs.AddFieldf(fmt.Sprintf("Dict"+".%v", kDict), "more than 34") } } for kDictDogs, vDictDogs := range r.DictDogs { - _ = kDictDogs - _ = vDictDogs if err := vDictDogs.ValidateOptional(); err != nil { - errs.AddField(fmt.Sprintf("DictDogs"+".%v", vDictDogs), err) + errs.AddField(fmt.Sprintf("DictDogs"+".%v", kDictDogs), err) } if err := validateMaxDogName(vDictDogs); err != nil { - errs.AddField(fmt.Sprintf("DictDogs"+".%v", vDictDogs), err) + errs.AddField(fmt.Sprintf("DictDogs"+".%v", kDictDogs), err) } } if err := r.Alias.Validate(); err != nil { @@ -202,30 +188,38 @@ func (r User) Validate() error { errs.AddField("AliasOnAliasWithCustomValidate", err) } for kMapOfMap, vMapOfMap := range r.MapOfMap { - _ = kMapOfMap - _ = vMapOfMap + if utf8.RuneCountInString(string(kMapOfMap)) < 3 { + errs.AddFieldf(fmt.Sprintf("MapOfMap"+".key[%v]", kMapOfMap), "shorter than 3 chars") + } if len(vMapOfMap) < 1 { - errs.AddFieldf(fmt.Sprintf("MapOfMap"+".%v", vMapOfMap), "less items than 1") + errs.AddFieldf(fmt.Sprintf("MapOfMap"+".%v", kMapOfMap), "less items than 1") } for kvMapOfMap, vvMapOfMap := range vMapOfMap { - _ = kvMapOfMap - _ = vvMapOfMap if utf8.RuneCountInString(string(vvMapOfMap)) < 3 { - errs.AddFieldf(fmt.Sprintf(fmt.Sprintf("MapOfMap"+".%v", vMapOfMap)+".%v", vvMapOfMap), "shorter than 3 chars") + errs.AddFieldf(fmt.Sprintf(fmt.Sprintf("MapOfMap"+".%v", kMapOfMap)+".%v", kvMapOfMap), "shorter than 3 chars") } } } for kMapOfSlice, vMapOfSlice := range r.MapOfSlice { - _ = kMapOfSlice - _ = vMapOfSlice if len(vMapOfSlice) < 1 { - errs.AddFieldf(fmt.Sprintf("MapOfSlice"+".%v", vMapOfSlice), "less items than 1") + errs.AddFieldf(fmt.Sprintf("MapOfSlice"+".%v", kMapOfSlice), "less items than 1") } for kvMapOfSlice, vvMapOfSlice := range vMapOfSlice { - _ = kvMapOfSlice - _ = vvMapOfSlice if utf8.RuneCountInString(string(vvMapOfSlice)) > 256 { - errs.AddFieldf(fmt.Sprintf(fmt.Sprintf("MapOfSlice"+".%v", vMapOfSlice)+".%v", kvMapOfSlice), "longer than 256 chars") + errs.AddFieldf(fmt.Sprintf(fmt.Sprintf("MapOfSlice"+".%v", kMapOfSlice)+".%v", kvMapOfSlice), "longer than 256 chars") + } + } + } + for kSliceOfMap, vSliceOfMap := range r.SliceOfMap { + if len(vSliceOfMap) < 1 { + errs.AddFieldf(fmt.Sprintf("SliceOfMap"+".%v", kSliceOfMap), "less items than 1") + } + for kvSliceOfMap, vvSliceOfMap := range vSliceOfMap { + if utf8.RuneCountInString(string(kvSliceOfMap)) < 3 { + errs.AddFieldf(fmt.Sprintf(fmt.Sprintf("SliceOfMap"+".%v", kSliceOfMap)+".key[%v]", kvSliceOfMap), "shorter than 3 chars") + } + if vvSliceOfMap < 1 { + errs.AddFieldf(fmt.Sprintf(fmt.Sprintf("SliceOfMap"+".%v", kSliceOfMap)+".%v", kvSliceOfMap), "less than 1") } } } @@ -233,20 +227,14 @@ func (r User) Validate() error { errs.AddFieldf("SliceOfSliceOfSlice", "less items than 1") } for kSliceOfSliceOfSlice, vSliceOfSliceOfSlice := range r.SliceOfSliceOfSlice { - _ = kSliceOfSliceOfSlice - _ = vSliceOfSliceOfSlice if len(vSliceOfSliceOfSlice) < 1 { errs.AddFieldf(fmt.Sprintf("SliceOfSliceOfSlice"+".%v", kSliceOfSliceOfSlice), "less items than 1") } for kvSliceOfSliceOfSlice, vvSliceOfSliceOfSlice := range vSliceOfSliceOfSlice { - _ = kvSliceOfSliceOfSlice - _ = vvSliceOfSliceOfSlice if len(vvSliceOfSliceOfSlice) < 1 { errs.AddFieldf(fmt.Sprintf(fmt.Sprintf("SliceOfSliceOfSlice"+".%v", kSliceOfSliceOfSlice)+".%v", kvSliceOfSliceOfSlice), "less items than 1") } for kvvSliceOfSliceOfSlice, vvvSliceOfSliceOfSlice := range vvSliceOfSliceOfSlice { - _ = kvvSliceOfSliceOfSlice - _ = vvvSliceOfSliceOfSlice if utf8.RuneCountInString(string(vvvSliceOfSliceOfSlice)) > 256 { errs.AddFieldf(fmt.Sprintf(fmt.Sprintf(fmt.Sprintf("SliceOfSliceOfSlice"+".%v", kSliceOfSliceOfSlice)+".%v", kvSliceOfSliceOfSlice)+".%v", kvvSliceOfSliceOfSlice), "longer than 256 chars") } diff --git a/examples/simple/validators.go b/examples/simple/validators.go index c47d8b5..2c9f15f 100644 --- a/examples/simple/validators.go +++ b/examples/simple/validators.go @@ -70,13 +70,11 @@ func (r User) Validate() error { errs.AddFieldf("Emails", "less items than 1") } for kEmails, vEmails := range r.Emails { - _ = kEmails - _ = vEmails if kEmails > 3 { - errs.AddFieldf(fmt.Sprintf("Emails"+".%v", kEmails), "more than 3") + errs.AddFieldf(fmt.Sprintf("Emails"+".key[%v]", kEmails), "more than 3") } if utf8.RuneCountInString(string(vEmails)) < 5 { - errs.AddFieldf(fmt.Sprintf("Emails"+".%v", vEmails), "shorter than 5 chars") + errs.AddFieldf(fmt.Sprintf("Emails"+".%v", kEmails), "shorter than 5 chars") } } if r.Title == nil { diff --git a/types/common.go b/types/common.go index cab5de4..74d25e8 100644 --- a/types/common.go +++ b/types/common.go @@ -69,7 +69,7 @@ func NewName(pointerPrefix, structVar, labelName, fieldName, tagName string) Nam } } -func NewIndexedName(labelName, indexVar, validateVar, tagName string) Name { +func NewIndexedValueName(labelName, indexVar, validateVar, tagName string) Name { return Name{ pointerPrefix: "", structVar: "", @@ -78,6 +78,17 @@ func NewIndexedName(labelName, indexVar, validateVar, tagName string) Name { tagName: tagName, } } + +func NewIndexedKeyName(labelName, indexVar, validateVar, tagName string) Name { + return Name{ + pointerPrefix: "", + structVar: "", + fieldName: validateVar, + labelName: fmt.Sprintf("fmt.Sprintf(%s + \".key[%%v]\", %v)", labelName, indexVar), + tagName: tagName, + } +} + func NewSimpleNameWithAliasType(fieldName, aliasType string) Name { return Name{ aliasType: &aliasType, diff --git a/types/type_array.go b/types/type_array.go index f639bfc..93533cd 100644 --- a/types/type_array.go +++ b/types/type_array.go @@ -65,10 +65,8 @@ func (t typeArray) Generate(w io.Writer, cfg GenConfig, name Name) { kName := "k" + name.fieldName vName := "v" + name.fieldName fmt.Fprintf(w, "for %s, %s := range %s {\n", kName, vName, name.Full()) - fmt.Fprintf(w, " _ = %s \n", kName) - fmt.Fprintf(w, " _ = %s \n", vName) cfg.AddImport("fmt") - t.innerType.Generate(w, cfg, NewIndexedName(name.labelName, kName, vName, name.tagName)) + t.innerType.Generate(w, cfg, NewIndexedValueName(name.labelName, kName, vName, name.tagName)) fmt.Fprintf(w, "}\n") } } diff --git a/types/type_map.go b/types/type_map.go index 70c7398..983b5c9 100644 --- a/types/type_map.go +++ b/types/type_map.go @@ -69,15 +69,19 @@ func (t typeMap) Generate(w io.Writer, cfg GenConfig, name Name) { fmt.Fprintf(w, "}\n") } - if t.key.NeedGenerate() || t.value.NeedGenerate() { - kName := "k" + name.fieldName - vName := "v" + name.fieldName + if keyNeedGenerate, valueNeedGenerate := t.key.NeedGenerate(), t.value.NeedGenerate(); keyNeedGenerate || valueNeedGenerate { + kName, vName := "k"+name.fieldName, "_" + if valueNeedGenerate { + vName = "v" + name.fieldName + } fmt.Fprintf(w, "for %s, %s := range %s {\n", kName, vName, name.Full()) - fmt.Fprintf(w, " _ = %s \n", kName) - fmt.Fprintf(w, " _ = %s \n", vName) cfg.AddImport("fmt") - t.key.Generate(w, cfg, NewIndexedName(name.labelName, kName, kName, name.tagName)) - t.value.Generate(w, cfg, NewIndexedName(name.labelName, vName, vName, name.tagName)) + if keyNeedGenerate { + t.key.Generate(w, cfg, NewIndexedKeyName(name.labelName, kName, kName, name.tagName)) + } + if valueNeedGenerate { + t.value.Generate(w, cfg, NewIndexedValueName(name.labelName, kName, vName, name.tagName)) + } fmt.Fprintf(w, "}\n") } } From 75ff99465f1294d85bc95c9f33a7958a565b9a55 Mon Sep 17 00:00:00 2001 From: Vadim Petrov Date: Fri, 29 Dec 2017 11:50:38 +0300 Subject: [PATCH 3/5] Add test cases --- Makefile | 1 + examples/complicated/entities_test.go | 66 +++++++++++++++++++++++++++ examples/simple/entities_test.go | 2 +- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 28163fc..78e1373 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ all: go build go generate + go test ./examples/... diff --git a/examples/complicated/entities_test.go b/examples/complicated/entities_test.go index bb85191..a1da708 100644 --- a/examples/complicated/entities_test.go +++ b/examples/complicated/entities_test.go @@ -34,6 +34,28 @@ func Test_Request1_Validate(t *testing.T) { "test": 1, "test_2": 2, }, + MapOfMap: map[string]map[int]string{ + "key": { + 1: "value", + }, + }, + MapOfSlice: map[string][]string{ + "key": { + "value", + }, + }, + SliceOfMap: []map[string]int{ + { + "key": 1, + }, + }, + SliceOfSliceOfSlice: [][][]string{ + { + { + "value", + }, + }, + }, } t.Run("valid", func(t *testing.T) { @@ -129,5 +151,49 @@ func Test_Request1_Validate(t *testing.T) { err := r.Validate() require.NoError(t, err) }) + + t.Run("MapOfMap: invalid value", func(t *testing.T) { + r := validUser + r.MapOfMap = map[string]map[int]string{ + "key": { + 1: "v", + }, + } + + err := r.Validate() + require.NotNil(t, err) + assert.Equal(t, `[MapOfMap.key.1: shorter than 3 chars]`, err.Error()) + }) + + t.Run("SliceOfMap: invalid key", func(t *testing.T) { + r := validUser + r.SliceOfMap = []map[string]int{ + { + "k": 1, + }, + } + + err := r.Validate() + require.NotNil(t, err) + assert.Equal(t, `[SliceOfMap.0.key[k]: shorter than 3 chars]`, err.Error()) + }) + + t.Run("SliceOfSliceOfSlice: invalid length", func(t *testing.T) { + r := validUser + r.SliceOfSliceOfSlice = [][][]string{ + { + { + "value", + }, + }, + { + {}, + }, + } + + err := r.Validate() + require.NotNil(t, err) + assert.Equal(t, `[SliceOfSliceOfSlice.1.0: less items than 1]`, err.Error()) + }) }) } diff --git a/examples/simple/entities_test.go b/examples/simple/entities_test.go index 4cc9244..8528117 100644 --- a/examples/simple/entities_test.go +++ b/examples/simple/entities_test.go @@ -77,7 +77,7 @@ func Test_User_Validate(t *testing.T) { err := user.Validate() require.NotNil(t, err) - assert.Equal(t, "[Emails.1111: more than 3, Emails.1111: shorter than 5 chars]", err.Error()) + assert.Equal(t, "[Emails.key[1111]: more than 3, Emails.1111: shorter than 5 chars]", err.Error()) }) t.Run("too young", func(t *testing.T) { From b0bc042160d5b63c1d07823a6588b1cab24ca871 Mon Sep 17 00:00:00 2001 From: Vadim Petrov Date: Fri, 29 Dec 2017 11:55:59 +0300 Subject: [PATCH 4/5] Update .travis.yml --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3a81bf9..141f477 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,9 @@ language: go go: - 1.7 - - tip \ No newline at end of file + - tip + +install: + - go get github.com/pkg/errors + - go get github.com/stretchr/testify/assert + - go get github.com/stretchr/testify/require \ No newline at end of file From b62ae7b3e40d538bb15e530fcff1a455d482e323 Mon Sep 17 00:00:00 2001 From: Vadim Petrov Date: Fri, 29 Dec 2017 12:18:25 +0300 Subject: [PATCH 5/5] Fix fmt.Errorf --- examples/complicated/constants.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/complicated/constants.go b/examples/complicated/constants.go index 595992a..4b04d4f 100644 --- a/examples/complicated/constants.go +++ b/examples/complicated/constants.go @@ -25,5 +25,5 @@ func (s State) Validate() error { //overriding if s > StateOk && s < StateError { return nil } - return fmt.Errorf("unrecognized state: %s", s) + return fmt.Errorf("unrecognized state: %v", s) }