From 1f6a5a458903a375b89d32f5a792dd564ecceee7 Mon Sep 17 00:00:00 2001 From: Alex Bice Date: Fri, 8 Dec 2017 16:23:09 -0700 Subject: [PATCH] Added support for embedded structs (#2) * Added support for embedded structs --- generator/example_test.go | 5 ++ generator/gencheck.go | 34 +++++++- glide.lock | 47 +++++++---- glide.yaml | 2 + internal/benchmark/types_validators.go | 112 ++++++++++++++++--------- internal/example/example.go | 5 ++ internal/example/example_test.go | 7 +- internal/example/example_validators.go | 30 ++++++- 8 files changed, 182 insertions(+), 60 deletions(-) diff --git a/generator/example_test.go b/generator/example_test.go index 62827c1..f4d5593 100644 --- a/generator/example_test.go +++ b/generator/example_test.go @@ -74,7 +74,12 @@ type Inner struct { LteCSFieldString string } +type Embedded struct { + FieldString string `valid:"required"` +} + type Test struct { + Embedded `valid:"dive"` Inner Inner RequiredString string `validate:"required"` RequiredNumber int `validate:"required"` diff --git a/generator/gencheck.go b/generator/gencheck.go index f58d5de..17c74c5 100644 --- a/generator/gencheck.go +++ b/generator/gencheck.go @@ -118,6 +118,25 @@ func (a byPosition) Len() int { return len(a) } func (a byPosition) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a byPosition) Less(i, j int) bool { return a[i].Pos() < a[j].Pos() } +func (g *Generator) expandEmbeddedFields(structs map[string]*ast.StructType, fields []*ast.Field) []*ast.Field { + sort.Sort(byPosition(fields)) + + actualFieldList := make([]*ast.Field, 0, len(fields)) + for _, field := range fields { + if len(field.Names) < 1 { + fieldName := g.getStringForExpr(field.Type) + if embedded, ok := structs[fieldName]; ok { + expanded := g.expandEmbeddedFields(structs, embedded.Fields.List) + actualFieldList = append(actualFieldList, expanded...) + } + } else { + actualFieldList = append(actualFieldList, field) + } + } + + return actualFieldList +} + // Generate does the heavy lifting for the code generation starting from the parsed AST file. func (g *Generator) Generate(f *ast.File) ([]byte, error) { var err error @@ -143,15 +162,22 @@ func (g *Generator) Generate(f *ast.File) ([]byte, error) { var rules []Field - fieldList := st.Fields.List - sort.Sort(byPosition(fieldList)) + // Only expands when we find an embedded struct + fieldList := g.expandEmbeddedFields(structs, st.Fields.List) // Go through the fields in the struct and find all the validated tags for _, field := range fieldList { + fieldName := `` + // Support for embedded structs that don't have a field name associated with it + if len(field.Names) > 0 { + fieldName = field.Names[0].Name + } else { + fieldName = g.getStringForExpr(field.Type) + } // Make a field holder f := Field{ F: field, - Name: field.Names[0].Name, + Name: fieldName, } g.getTypeString(&f) @@ -253,7 +279,7 @@ func (g *Generator) Generate(f *ast.File) ([]byte, error) { formatted, err := imports.Process(pkg, vBuff.Bytes(), nil) if err != nil { - err = fmt.Errorf("generate: error formatting code %s\n\n%s\n", err, string(vBuff.Bytes())) + err = fmt.Errorf("generate: error formatting code %s\n\n%s\n", err, vBuff.String()) } return formatted, err } diff --git a/glide.lock b/glide.lock index a34cf2f..fb80aff 100644 --- a/glide.lock +++ b/glide.lock @@ -1,27 +1,35 @@ -hash: 6cb65405e8a3d5edc04c62f4f1c46f35afd340b58964d9b07619d46a2b8ac0a7 -updated: 2016-12-20T08:23:56.426690306-07:00 +hash: 40d2cec98391915d5d8afe55943afadef44c1c23d1b00226e48aa421b7fffd1a +updated: 2017-12-08T15:34:43.895843119-07:00 imports: - name: github.com/aokoli/goutils - version: 9c37978a95bd5c709a15883b6242714ea6709e64 + version: 3391d3790d23d03408670993e957e8f408993c34 - name: github.com/Bowery/prompt - version: d43c2707a6c5a152a344c64bb4fed657e2908a81 + version: 753711fea478fa77bb2c83f6ec244b814d4a8bad +- name: github.com/huandu/xstrings + version: 37469d0c81a7910b49d64a0d308ded4823e90937 +- name: github.com/imdario/mergo + version: 7fe0c75c13abdee74b09fcacef5ea1c6bba6a874 - name: github.com/labstack/gommon - version: 2d272df536d051e737aea353b86c979d6e88bce0 + version: 57409ada9da0f2afad6664c49502f8c50fbd8476 subpackages: - color +- name: github.com/Masterminds/semver + version: 59c29afe1a994eacb71c833025ca7acf874bb1da - name: github.com/Masterminds/sprig - version: 1e60e4ce482a1e2c7b9c9be667535ef152e04300 + version: b217b9c388de2cacde4354c536e520c52c055563 - name: github.com/mattn/go-colorable - version: 6c903ff4aa50920ca86087a280590b36b3152b9c + version: 6fcc0c1fd9b620311d821b106a400b35dc95c497 - name: github.com/mattn/go-isatty - version: 66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8 + version: 6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c - name: github.com/mkideal/cli - version: 72ac83b12b73f6e83ee1aee30310c264c46f9270 + version: a9c1104566927924fdb041d198f05617492913f9 - name: github.com/mkideal/pkg - version: 05c9bbf4a905cf1a0ddebba440bf8d522e1d4976 + version: 3e188c9e7ecc83d0fe7040a9161ce3c67885470d subpackages: - debug - expr +- name: github.com/pkg/errors + version: 645ef00459ed84a119197bfb8d8205042c6df63d - name: github.com/satori/go.uuid version: 879c5887cd475cd7864858769793b2ceb0d44feb - name: github.com/stretchr/testify @@ -30,27 +38,38 @@ imports: - assert - require - suite +- name: golang.org/x/crypto + version: b080dc9a8c480b08e698fb1219160d598526310f + subpackages: + - pbkdf2 + - scrypt - name: golang.org/x/sys - version: c200b10b5d5e122be351b67af224adc6128af5bf + version: 4ff8c001ce4cc464e644b922325097228fce14d8 subpackages: - unix - name: golang.org/x/text - version: 5722c1c97facbc41d1f9329ce722ed374db7d819 + version: 88f656faf3f37f690df1a32515b479415e1a6769 subpackages: - internal/tag - language - name: golang.org/x/tools - version: 6d7cee0134e889eb7e1f17662ea1881d5a6ffb42 + version: a5ff95640e8c289d9c807a532e8110268036c0dd subpackages: - go/ast/astutil - imports - name: gopkg.in/go-playground/validator.v9 - version: 49fccadad19338f93f46a5abdafc44cd731cf7a7 + version: 61caf9d3038e1af346dbf5c2e16f6678e1548364 testImports: - name: github.com/davecgh/go-spew version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 subpackages: - spew +- name: github.com/go-playground/locales + version: e4cbcb5d0652150d40ad0646651076b6bd2be4f6 + subpackages: + - currency +- name: github.com/go-playground/universal-translator + version: 71201497bace774495daed26a3874fd339e0b538 - name: github.com/pmezard/go-difflib version: d8ed2627bdf02c080bf22230dbb337003b7aba2d subpackages: diff --git a/glide.yaml b/glide.yaml index 3cd06c9..4dc5bd1 100644 --- a/glide.yaml +++ b/glide.yaml @@ -10,3 +10,5 @@ import: version: ^1.1.4 - package: gopkg.in/go-playground/validator.v9 version: ^9.3.1 +- package: github.com/pkg/errors + version: v0.8.0 diff --git a/internal/benchmark/types_validators.go b/internal/benchmark/types_validators.go index 9075ff7..dd5cbc6 100755 --- a/internal/benchmark/types_validators.go +++ b/internal/benchmark/types_validators.go @@ -18,15 +18,19 @@ import ( // See https://github.com/abice/gencheck for more details. func (s SingleString) Validate() error { - var vErrors gencheck.ValidationErrors + vErrors := make(gencheck.ValidationErrors, 0, 1) // BEGIN Entry Validations // required if s.Entry == "" { - return append(vErrors, gencheck.NewFieldError("SingleString", "Entry", "required", errors.New("is required"))) + vErrors = append(vErrors, gencheck.NewFieldError("SingleString", "Entry", "required", errors.New("is required"))) } // END Entry Validations + if len(vErrors) > 0 { + return vErrors + } + return nil } @@ -35,46 +39,46 @@ func (s SingleString) Validate() error { // See https://github.com/abice/gencheck for more details. func (s TestAll) Validate() error { - var vErrors gencheck.ValidationErrors + vErrors := make(gencheck.ValidationErrors, 0, 17) // BEGIN Required Validations // required if s.Required == "" { - return append(vErrors, gencheck.NewFieldError("TestAll", "Required", "required", errors.New("is required"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "Required", "required", errors.New("is required"))) } // END Required Validations // BEGIN Len Validations // len if !(len(s.Len) == 10) { - return append(vErrors, gencheck.NewFieldError("TestAll", "Len", "len", errors.New("length mismatch"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "Len", "len", errors.New("length mismatch"))) } // END Len Validations // BEGIN Min Validations // min if len(s.Min) < 5 { - return append(vErrors, gencheck.NewFieldError("TestAll", "Min", "min", errors.New("length failed check for min=5"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "Min", "min", errors.New("length failed check for min=5"))) } // END Min Validations // BEGIN Max Validations // max if len(s.Max) > 100 { - return append(vErrors, gencheck.NewFieldError("TestAll", "Max", "max", errors.New("length failed check for max=100"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "Max", "max", errors.New("length failed check for max=100"))) } // END Max Validations // BEGIN CIDR Validations // required if s.CIDR == "" { - return append(vErrors, gencheck.NewFieldError("TestAll", "CIDR", "required", errors.New("is required"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "CIDR", "required", errors.New("is required"))) } // cidr _, _, CIDRerr := net.ParseCIDR(s.CIDR) if CIDRerr != nil { - return append(vErrors, gencheck.NewFieldError("TestAll", "CIDR", "cidr", CIDRerr)) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "CIDR", "cidr", CIDRerr)) } // END CIDR Validations @@ -82,7 +86,7 @@ func (s TestAll) Validate() error { // lte tLteTime := time.Now().UTC() if s.LteTime.After(tLteTime) { - return append(vErrors, gencheck.NewFieldError("TestAll", "LteTime", "lte", errors.New("is after now"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "LteTime", "lte", errors.New("is after now"))) } // END LteTime Validations @@ -90,69 +94,69 @@ func (s TestAll) Validate() error { // gte tGteTime := time.Now().UTC() if s.GteTime.Before(tGteTime) { - return append(vErrors, gencheck.NewFieldError("TestAll", "GteTime", "gte", errors.New("is before now"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "GteTime", "gte", errors.New("is before now"))) } // END GteTime Validations // BEGIN Gte Validations // gte if s.Gte < 1.2345 { - return append(vErrors, gencheck.NewFieldError("TestAll", "Gte", "gte", errors.New("failed check for gte=1.2345"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "Gte", "gte", errors.New("failed check for gte=1.2345"))) } // END Gte Validations // BEGIN NotNil Validations // required if s.NotNil == nil { - return append(vErrors, gencheck.NewFieldError("TestAll", "NotNil", "required", errors.New("is required"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "NotNil", "required", errors.New("is required"))) } // END NotNil Validations // BEGIN Contains Validations // contains if !strings.Contains(s.Contains, "fox") { - return append(vErrors, gencheck.NewFieldError("TestAll", "Contains", "contains", errors.New("Contains did not contain fox"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "Contains", "contains", errors.New("Contains did not contain fox"))) } // END Contains Validations // BEGIN Hex Validations // hex if err := gencheck.IsHex(&s.Hex); err != nil { - return append(vErrors, gencheck.NewFieldError("TestAll", "Hex", "hex", err)) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "Hex", "hex", err)) } // END Hex Validations // BEGIN UUID Validations // uuid if err := gencheck.IsUUID(&s.UUID); err != nil { - return append(vErrors, gencheck.NewFieldError("TestAll", "UUID", "uuid", err)) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "UUID", "uuid", err)) } // END UUID Validations // BEGIN MinInt Validations // min if s.MinInt < 12345 { - return append(vErrors, gencheck.NewFieldError("TestAll", "MinInt", "min", errors.New("failed check for min=12345"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "MinInt", "min", errors.New("failed check for min=12345"))) } // END MinInt Validations // BEGIN MaxInt Validations // max if s.MaxInt > 12345 { - return append(vErrors, gencheck.NewFieldError("TestAll", "MaxInt", "max", errors.New("failed check for max=12345"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "MaxInt", "max", errors.New("failed check for max=12345"))) } // END MaxInt Validations // BEGIN Dive Validations // required if s.Dive == nil { - return append(vErrors, gencheck.NewFieldError("TestAll", "Dive", "required", errors.New("is required"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "Dive", "required", errors.New("is required"))) } // dive if s.Dive != nil { if err := gencheck.Validate(s.Dive); err != nil { - return append(vErrors, gencheck.NewFieldError("TestAll", "Dive", "dive", err)) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "Dive", "dive", err)) } } // END Dive Validations @@ -162,9 +166,9 @@ func (s TestAll) Validate() error { if s.URL != "" { URLURL, URLurlerr := url.ParseRequestURI(s.URL) if URLurlerr != nil { - return append(vErrors, gencheck.NewFieldError("TestAll", "URL", "url", URLurlerr)) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "URL", "url", URLurlerr)) } else if URLURL.Scheme == "" { - return append(vErrors, gencheck.NewFieldError("TestAll", "URL", "url", errors.New("URL is missing a scheme"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "URL", "url", errors.New("URL is missing a scheme"))) } } // END URL Validations @@ -174,11 +178,15 @@ func (s TestAll) Validate() error { if s.URI != "" { _, URIurierr := url.ParseRequestURI(s.URI) if URIurierr != nil { - return append(vErrors, gencheck.NewFieldError("TestAll", "URI", "uri", URIurierr)) + vErrors = append(vErrors, gencheck.NewFieldError("TestAll", "URI", "uri", URIurierr)) } } // END URI Validations + if len(vErrors) > 0 { + return vErrors + } + return nil } @@ -187,15 +195,19 @@ func (s TestAll) Validate() error { // See https://github.com/abice/gencheck for more details. func (s TestContainsAny) Validate() error { - var vErrors gencheck.ValidationErrors + vErrors := make(gencheck.ValidationErrors, 0, 1) // BEGIN Any Validations // containsany if !strings.ContainsAny(s.Any, "@#!") { - return append(vErrors, gencheck.NewFieldError("TestContainsAny", "Any", "containsany", errors.New("Any did not contain any of @#!"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestContainsAny", "Any", "containsany", errors.New("Any did not contain any of @#!"))) } // END Any Validations + if len(vErrors) > 0 { + return vErrors + } + return nil } @@ -204,22 +216,26 @@ func (s TestContainsAny) Validate() error { // See https://github.com/abice/gencheck for more details. func (s TestDive) Validate() error { - var vErrors gencheck.ValidationErrors + vErrors := make(gencheck.ValidationErrors, 0, 1) // BEGIN Value Validations // required if s.Value == nil { - return append(vErrors, gencheck.NewFieldError("TestDive", "Value", "required", errors.New("is required"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestDive", "Value", "required", errors.New("is required"))) } // dive if s.Value != nil { if err := gencheck.Validate(s.Value); err != nil { - return append(vErrors, gencheck.NewFieldError("TestDive", "Value", "dive", err)) + vErrors = append(vErrors, gencheck.NewFieldError("TestDive", "Value", "dive", err)) } } // END Value Validations + if len(vErrors) > 0 { + return vErrors + } + return nil } @@ -228,15 +244,19 @@ func (s TestDive) Validate() error { // See https://github.com/abice/gencheck for more details. func (s TestHex) Validate() error { - var vErrors gencheck.ValidationErrors + vErrors := make(gencheck.ValidationErrors, 0, 1) // BEGIN Value Validations // hex if err := gencheck.IsHex(&s.Value); err != nil { - return append(vErrors, gencheck.NewFieldError("TestHex", "Value", "hex", err)) + vErrors = append(vErrors, gencheck.NewFieldError("TestHex", "Value", "hex", err)) } // END Value Validations + if len(vErrors) > 0 { + return vErrors + } + return nil } @@ -245,15 +265,19 @@ func (s TestHex) Validate() error { // See https://github.com/abice/gencheck for more details. func (s TestMap) Validate() error { - var vErrors gencheck.ValidationErrors + vErrors := make(gencheck.ValidationErrors, 0, 1) // BEGIN Value Validations // contains if _, foundValue := s.Value["test"]; !foundValue { - return append(vErrors, gencheck.NewFieldError("TestMap", "Value", "contains", errors.New("Value did not contain test"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestMap", "Value", "contains", errors.New("Value did not contain test"))) } // END Value Validations + if len(vErrors) > 0 { + return vErrors + } + return nil } @@ -262,36 +286,40 @@ func (s TestMap) Validate() error { // See https://github.com/abice/gencheck for more details. func (s TestString) Validate() error { - var vErrors gencheck.ValidationErrors + vErrors := make(gencheck.ValidationErrors, 0, 4) // BEGIN Required Validations // required if s.Required == "" { - return append(vErrors, gencheck.NewFieldError("TestString", "Required", "required", errors.New("is required"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestString", "Required", "required", errors.New("is required"))) } // END Required Validations // BEGIN Len Validations // len if !(len(s.Len) == 10) { - return append(vErrors, gencheck.NewFieldError("TestString", "Len", "len", errors.New("length mismatch"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestString", "Len", "len", errors.New("length mismatch"))) } // END Len Validations // BEGIN Min Validations // min if len(s.Min) < 5 { - return append(vErrors, gencheck.NewFieldError("TestString", "Min", "min", errors.New("length failed check for min=5"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestString", "Min", "min", errors.New("length failed check for min=5"))) } // END Min Validations // BEGIN Max Validations // max if len(s.Max) > 100 { - return append(vErrors, gencheck.NewFieldError("TestString", "Max", "max", errors.New("length failed check for max=100"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestString", "Max", "max", errors.New("length failed check for max=100"))) } // END Max Validations + if len(vErrors) > 0 { + return vErrors + } + return nil } @@ -300,19 +328,23 @@ func (s TestString) Validate() error { // See https://github.com/abice/gencheck for more details. func (s TestUUID) Validate() error { - var vErrors gencheck.ValidationErrors + vErrors := make(gencheck.ValidationErrors, 0, 1) // BEGIN UUID Validations // required if s.UUID == "" { - return append(vErrors, gencheck.NewFieldError("TestUUID", "UUID", "required", errors.New("is required"))) + vErrors = append(vErrors, gencheck.NewFieldError("TestUUID", "UUID", "required", errors.New("is required"))) } // uuid if err := gencheck.IsUUID(&s.UUID); err != nil { - return append(vErrors, gencheck.NewFieldError("TestUUID", "UUID", "uuid", err)) + vErrors = append(vErrors, gencheck.NewFieldError("TestUUID", "UUID", "uuid", err)) } // END UUID Validations + if len(vErrors) > 0 { + return vErrors + } + return nil } diff --git a/internal/example/example.go b/internal/example/example.go index ced556c..c985f5a 100644 --- a/internal/example/example.go +++ b/internal/example/example.go @@ -24,8 +24,13 @@ type Inner struct { LteCSFieldString string } +type Embedded struct { + FieldString string `valid:"required"` +} + // Test is a test struct for testing. type Test struct { + Embedded Inner Inner // RequiredNumber int `valid:"required"` RequiredString string `valid:"required,ff"` diff --git a/internal/example/example_test.go b/internal/example/example_test.go index e378dfa..819d181 100644 --- a/internal/example/example_test.go +++ b/internal/example/example_test.go @@ -30,6 +30,7 @@ func (s *ExampleTestSuite) TestValidateTestStruct_FailFast() { } underTest := Test{ + Embedded: Embedded{FieldString: `1234`}, MaxString: "1234", MaxNumber: 1113.00001, MaxMultiple: []string{"", "", "", "", "", "", "", "", ""}, @@ -50,6 +51,7 @@ func (s *ExampleTestSuite) TestValidateTestStruct_FailFast() { // TestValidateTestStruct_NoValues func (s *ExampleTestSuite) TestValidateTestStruct_NoValues() { expected := gencheck.ValidationErrors{ + gencheck.NewFieldError("Test", "FieldString", "required", fmt.Errorf("is required")), gencheck.NewFieldError("Test", "RequiredMultiple", "required", fmt.Errorf("is required")), gencheck.NewFieldError("Test", "LenString", "len", fmt.Errorf("length mismatch")), gencheck.NewFieldError("Test", "LenNumber", "len", fmt.Errorf("length mismatch")), @@ -137,6 +139,7 @@ func (s *ExampleTestSuite) TestValidateTestStruct_NoValues() { func (s *ExampleTestSuite) TestValidateTestStruct_Values() { i := int64(2000) underTest := Test{ + Embedded: Embedded{FieldString: `1234`}, LenMultiple: []string{"", "", "", "", "", "", ""}, LenNumber: 1113, LenString: "a", @@ -189,6 +192,7 @@ func (s *ExampleTestSuite) TestValidateTestStruct_Values() { func (s *ExampleTestSuite) TestValidateTestStruct_MinPtrFailure() { i := int64(1233) underTest := Test{ + Embedded: Embedded{FieldString: `1234`}, LenMultiple: []string{"", "", "", "", "", "", ""}, LenNumber: 1113, LenString: "a", @@ -269,6 +273,7 @@ func (s *ExampleTestSuite) TestValidateExample_Happy() { func (s *ExampleTestSuite) TestValidateTestStruct_LteTime() { i := int64(1234) underTest := Test{ + Embedded: Embedded{FieldString: `1234`}, LenMultiple: []string{"", "", "", "", "", "", ""}, LenNumber: 1113, LenString: "a", @@ -368,7 +373,7 @@ func TestValidateTestStruct_Individual(t *testing.T) { for _, e := range ve { if e.Field() == test.field { found = true - assert.EqualValues(tt, e, test.expected, "Error did not match expected") + assert.EqualValues(tt, test.expected, e, "Error did not match expected") } } assert.True(tt, found, `Did not find expected error for field '%s'`, test.field) diff --git a/internal/example/example_validators.go b/internal/example/example_validators.go index 25400d2..f29d984 100755 --- a/internal/example/example_validators.go +++ b/internal/example/example_validators.go @@ -14,6 +14,27 @@ import ( "github.com/abice/gencheck" ) +// Validate is an automatically generated validation method provided by +// gencheck. +// See https://github.com/abice/gencheck for more details. +func (s Embedded) Validate() error { + + vErrors := make(gencheck.ValidationErrors, 0, 1) + + // BEGIN FieldString Validations + // required + if s.FieldString == "" { + vErrors = append(vErrors, gencheck.NewFieldError("Embedded", "FieldString", "required", errors.New("is required"))) + } + // END FieldString Validations + + if len(vErrors) > 0 { + return vErrors + } + + return nil +} + // Validate is an automatically generated validation method provided by // gencheck. // See https://github.com/abice/gencheck for more details. @@ -61,7 +82,14 @@ func (s Inner) Validate() error { // See https://github.com/abice/gencheck for more details. func (s Test) Validate() error { - vErrors := make(gencheck.ValidationErrors, 0, 53) + vErrors := make(gencheck.ValidationErrors, 0, 54) + + // BEGIN FieldString Validations + // required + if s.FieldString == "" { + vErrors = append(vErrors, gencheck.NewFieldError("Test", "FieldString", "required", errors.New("is required"))) + } + // END FieldString Validations // BEGIN RequiredString Validations // required