From e0e24c8e7ff92149dd9bc013acb7840d0ba368b3 Mon Sep 17 00:00:00 2001 From: Yu Huang Date: Sun, 23 May 2021 10:04:23 -0400 Subject: [PATCH 1/2] supports field formatter --- parser/parser.go | 19 ++++++++++++++----- parser/parser_test.go | 12 ++++++++++-- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/parser/parser.go b/parser/parser.go index 2b93e3a..d20964f 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -10,6 +10,11 @@ import ( "go/types" ) +// FieldFormatter transfers the field value to expected format +type FieldFormatter interface { + Format(field *StructField) string +} + // StructField defines struct field type StructField struct { Name string @@ -18,6 +23,7 @@ type StructField struct { Comment string Doc string Tag string + FormatFunc func(field *StructField) string } // Key returns the key of the field @@ -32,7 +38,7 @@ func (sf *StructField) Value() interface{} { return sf.NestedType.ToKV() } - return "" + return sf.FormatFunc(sf) } // StructNode defines struct node @@ -52,15 +58,16 @@ func (sn *StructNode) ToKV() map[string]interface{} { // StructParser parses structs in given file or string type StructParser struct { - MainStruct *StructNode - Info types.Info + MainStruct *StructNode + Info types.Info + FieldFormatter FieldFormatter } // NewStructParser is the constructor of StructParser // filePath and src follow the same rule with go/parser.ParseFile // If src != nil, ParseFile parses the source from src and the filename is only used when recording position information. The type of the argument for the src parameter must be string, []byte, or io.Reader. If src == nil, ParseFile parses the file specified by filename. // rootStruct is the root struct we want to use -func NewStructParser(filePath string, src interface{}, rootStruct string) (*StructParser, error) { +func NewStructParser(filePath string, src interface{}, rootStruct string, formatter FieldFormatter) (*StructParser, error) { fset := token.NewFileSet() f, err := parser.ParseFile(fset, filePath, src, parser.ParseComments) if err != nil { @@ -81,7 +88,8 @@ func NewStructParser(filePath string, src interface{}, rootStruct string) (*Stru } cg := &StructParser{ - Info: info, + FieldFormatter: formatter, + Info: info, } ast.Inspect(f, func(n ast.Node) bool { @@ -165,6 +173,7 @@ func (cg *StructParser) ParseField(field *ast.Field) *StructField { Comment: fieldComment, Doc: fieldDoc, NestedType: nestedStruct, + FormatFunc: cg.FieldFormatter.Format, } } diff --git a/parser/parser_test.go b/parser/parser_test.go index 4ba578a..5828aa9 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -5,6 +5,13 @@ import ( "log" ) +type sampleFormatter struct { +} + +func (f *sampleFormatter) Format(field *StructField) string { + return "" +} + func ExampleStructParser() { const src = ` package p @@ -28,9 +35,10 @@ type StructA struct { Field6 func(int) Field7 StructB } - ` - cg, err := NewStructParser("src.go", src, "StructA") + formatter := &sampleFormatter{} + + cg, err := NewStructParser("src.go", src, "StructA", formatter) if err != nil { log.Fatal(err) } From 7d3817ce1a402b763b16af50df5251fd93ee5639 Mon Sep 17 00:00:00 2001 From: Yu Huang Date: Sun, 23 May 2021 10:19:48 -0400 Subject: [PATCH 2/2] update parameter name --- parser/parser.go | 26 +++++++++++++------------- parser/parser_test.go | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/parser/parser.go b/parser/parser.go index d20964f..15d0fe6 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -87,7 +87,7 @@ func NewStructParser(filePath string, src interface{}, rootStruct string, format return nil, err } - cg := &StructParser{ + sp := &StructParser{ FieldFormatter: formatter, Info: info, } @@ -109,27 +109,27 @@ func NewStructParser(filePath string, src interface{}, rootStruct string, format return true } - cg.MainStruct = cg.ParseStruct(structName, s) + sp.MainStruct = sp.ParseStruct(structName, s) return false }) - if cg.MainStruct == nil { + if sp.MainStruct == nil { return nil, errors.New("non-exist root struct") } - return cg, nil + return sp, nil } -func (cg *StructParser) ToJSON() ([]byte, error) { - value := cg.MainStruct.ToKV() +func (sp *StructParser) ToJSON() ([]byte, error) { + value := sp.MainStruct.ToKV() return json.MarshalIndent(value, "", " ") } // ParseField parses struct field in nested way -func (cg *StructParser) ParseField(field *ast.Field) *StructField { +func (sp *StructParser) ParseField(field *ast.Field) *StructField { // ast.Print(nil, field) fieldName := field.Names[0].Name - fieldType := cg.Info.TypeOf(field.Type) + fieldType := sp.Info.TypeOf(field.Type) fieldTag := "" if field.Tag != nil { @@ -146,7 +146,7 @@ func (cg *StructParser) ParseField(field *ast.Field) *StructField { var nestedStruct *StructNode if s, isInlineStruct := field.Type.(*ast.StructType); isInlineStruct { - nestedStruct = cg.ParseStruct("", s) + nestedStruct = sp.ParseStruct("", s) } if _, isNamedStructorBasic := field.Type.(*ast.Ident); isNamedStructorBasic && field.Type.(*ast.Ident).Obj != nil { @@ -159,7 +159,7 @@ func (cg *StructParser) ParseField(field *ast.Field) *StructField { if !ok { return nil } - nestedStruct = cg.ParseStruct(ts.Name.Name, s) + nestedStruct = sp.ParseStruct(ts.Name.Name, s) } // fieldType.(*types.Basic) // basic type // *ast.ArrayType: @@ -173,15 +173,15 @@ func (cg *StructParser) ParseField(field *ast.Field) *StructField { Comment: fieldComment, Doc: fieldDoc, NestedType: nestedStruct, - FormatFunc: cg.FieldFormatter.Format, + FormatFunc: sp.FieldFormatter.Format, } } // ParseStruct parses struct in nested way -func (cg *StructParser) ParseStruct(structName string, s *ast.StructType) *StructNode { +func (sp *StructParser) ParseStruct(structName string, s *ast.StructType) *StructNode { fields := []*StructField{} for _, field := range s.Fields.List { - parsedField := cg.ParseField(field) + parsedField := sp.ParseField(field) if parsedField != nil { fields = append(fields, parsedField) } diff --git a/parser/parser_test.go b/parser/parser_test.go index 5828aa9..9413765 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -38,12 +38,12 @@ type StructA struct { ` formatter := &sampleFormatter{} - cg, err := NewStructParser("src.go", src, "StructA", formatter) + sp, err := NewStructParser("src.go", src, "StructA", formatter) if err != nil { log.Fatal(err) } - b, err := cg.ToJSON() + b, err := sp.ToJSON() if err != nil { log.Fatal(err) }