Skip to content

Commit

Permalink
Added support for embedded structs (#2)
Browse files Browse the repository at this point in the history
* Added support for embedded structs
  • Loading branch information
abice authored Dec 8, 2017
1 parent 8f04c59 commit 1f6a5a4
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 60 deletions.
5 changes: 5 additions & 0 deletions generator/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down
34 changes: 30 additions & 4 deletions generator/gencheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)

Expand Down Expand Up @@ -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
}
Expand Down
47 changes: 33 additions & 14 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading

0 comments on commit 1f6a5a4

Please sign in to comment.