Fix struct tag with spaces as values (#36)
This commit is contained in:
parent
bdb63c8129
commit
021de6214c
9 changed files with 38 additions and 86 deletions
|
@ -3,6 +3,7 @@ package code
|
|||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
@ -60,7 +61,7 @@ func extractStructType(name string, structType *ast.StructType) Struct {
|
|||
}
|
||||
strField.Type = getType(field.Type)
|
||||
if field.Tag != nil {
|
||||
strField.Tags = extractStructTag(field.Tag.Value)
|
||||
strField.Tag = extractStructTag(field.Tag.Value)
|
||||
}
|
||||
|
||||
str.Fields = append(str.Fields, strField)
|
||||
|
@ -103,26 +104,8 @@ func extractInterfaceType(name string, interfaceType *ast.InterfaceType) Interfa
|
|||
return intf
|
||||
}
|
||||
|
||||
func extractStructTag(tagValue string) map[string][]string {
|
||||
tagTokens := strings.Fields(tagValue[1 : len(tagValue)-1])
|
||||
|
||||
tags := make(map[string][]string)
|
||||
for _, tagToken := range tagTokens {
|
||||
colonIndex := strings.Index(tagToken, ":")
|
||||
if colonIndex == -1 {
|
||||
continue
|
||||
}
|
||||
tagKey := tagToken[:colonIndex]
|
||||
tagValue, err := strconv.Unquote(tagToken[colonIndex+1:])
|
||||
if err != nil {
|
||||
fmt.Printf("cannot unquote struct tag %s : %s\n", tagToken[colonIndex+1:], err)
|
||||
continue
|
||||
}
|
||||
tagValues := strings.Split(tagValue, ",")
|
||||
tags[tagKey] = tagValues
|
||||
}
|
||||
|
||||
return tags
|
||||
func extractStructTag(tagValue string) reflect.StructTag {
|
||||
return reflect.StructTag(tagValue[1 : len(tagValue)-1])
|
||||
}
|
||||
|
||||
func extractFunction(name string, comments []string, funcType *ast.FuncType) Method {
|
||||
|
|
|
@ -61,6 +61,7 @@ import (
|
|||
type UserModel struct {
|
||||
ID primitive.ObjectID ` + "`bson:\"_id,omitempty\" json:\"id\"`" + `
|
||||
Username string ` + "`bson:\"username\" json:\"username\"`" + `
|
||||
Password string ` + "`bson:\"password\" json:\"-\" note:\"This should be hidden.\"`" + `
|
||||
}`,
|
||||
ExpectedOutput: code.File{
|
||||
PackageName: "user",
|
||||
|
@ -71,18 +72,17 @@ type UserModel struct {
|
|||
code.StructField{
|
||||
Name: "ID",
|
||||
Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"},
|
||||
Tags: map[string][]string{
|
||||
"bson": {"_id", "omitempty"},
|
||||
"json": {"id"},
|
||||
},
|
||||
Tag: `bson:"_id,omitempty" json:"id"`,
|
||||
},
|
||||
code.StructField{
|
||||
Name: "Username",
|
||||
Type: code.TypeString,
|
||||
Tags: map[string][]string{
|
||||
"bson": {"username"},
|
||||
"json": {"username"},
|
||||
Tag: `bson:"username" json:"username"`,
|
||||
},
|
||||
code.StructField{
|
||||
Name: "Password",
|
||||
Type: code.TypeString,
|
||||
Tag: `bson:"password" json:"-" note:"This should be hidden."`,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -268,18 +268,12 @@ type UserRepository interface {
|
|||
code.StructField{
|
||||
Name: "ID",
|
||||
Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"},
|
||||
Tags: map[string][]string{
|
||||
"bson": {"_id", "omitempty"},
|
||||
"json": {"id"},
|
||||
},
|
||||
Tag: `bson:"_id,omitempty" json:"id"`,
|
||||
},
|
||||
code.StructField{
|
||||
Name: "Username",
|
||||
Type: code.TypeString,
|
||||
Tags: map[string][]string{
|
||||
"bson": {"username"},
|
||||
"json": {"username"},
|
||||
},
|
||||
Tag: `bson:"username" json:"username"`,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -2,6 +2,7 @@ package code
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// File is a container of all required components for code generation in the file
|
||||
|
@ -46,7 +47,7 @@ func (fields StructFields) ByName(name string) (StructField, bool) {
|
|||
type StructField struct {
|
||||
Name string
|
||||
Type Type
|
||||
Tags map[string][]string
|
||||
Tag reflect.StructTag
|
||||
}
|
||||
|
||||
// InterfaceType is a definition of the interface
|
||||
|
|
|
@ -62,10 +62,7 @@ func TestBuilderBuild(t *testing.T) {
|
|||
PackageAlias: "primitive",
|
||||
Name: "ObjectID",
|
||||
},
|
||||
Tags: map[string][]string{
|
||||
"bson": {"id"},
|
||||
"json": {"id", "omitempty"},
|
||||
},
|
||||
Tag: `bson:"id" json:"id,omitempty"`,
|
||||
},
|
||||
{
|
||||
Name: "Username",
|
||||
|
|
|
@ -3,7 +3,6 @@ package codegen
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
|
@ -39,25 +38,10 @@ func (sb StructBuilder) GenFields() string {
|
|||
var fieldLines []string
|
||||
for _, field := range sb.Fields {
|
||||
fieldLine := fmt.Sprintf("\t%s %s", field.Name, field.Type.Code())
|
||||
if len(field.Tags) > 0 {
|
||||
fieldLine += fmt.Sprintf(" `%s`", sb.generateStructTag(field.Tags))
|
||||
if len(field.Tag) > 0 {
|
||||
fieldLine += fmt.Sprintf(" `%s`", string(field.Tag))
|
||||
}
|
||||
fieldLines = append(fieldLines, fieldLine)
|
||||
}
|
||||
return strings.Join(fieldLines, "\n")
|
||||
}
|
||||
|
||||
func (sb StructBuilder) generateStructTag(tags map[string][]string) string {
|
||||
var tagKeys []string
|
||||
for key := range tags {
|
||||
tagKeys = append(tagKeys, key)
|
||||
}
|
||||
sort.Strings(tagKeys)
|
||||
|
||||
var tagGroups []string
|
||||
for _, key := range tagKeys {
|
||||
tagValue := strings.Join(tags[key], ",")
|
||||
tagGroups = append(tagGroups, fmt.Sprintf("%s:\"%s\"", key, tagValue))
|
||||
}
|
||||
return strings.Join(tagGroups, " ")
|
||||
}
|
||||
|
|
|
@ -28,25 +28,17 @@ func TestStructBuilderBuild(t *testing.T) {
|
|||
PackageAlias: "primitive",
|
||||
Name: "ObjectID",
|
||||
},
|
||||
Tags: map[string][]string{
|
||||
"json": {"id", "omitempty"},
|
||||
"bson": {"id", "omitempty"},
|
||||
},
|
||||
Tag: `bson:"id,omitempty" json:"id,omitempty"`,
|
||||
},
|
||||
{
|
||||
Name: "Username",
|
||||
Type: code.TypeString,
|
||||
Tags: map[string][]string{
|
||||
"json": {"username"},
|
||||
"bson": {"username"},
|
||||
},
|
||||
Tag: `bson:"username" json:"username"`,
|
||||
},
|
||||
{
|
||||
Name: "Age",
|
||||
Type: code.TypeInt,
|
||||
Tags: map[string][]string{
|
||||
"bson": {"age"},
|
||||
},
|
||||
Tag: `bson:"age"`,
|
||||
},
|
||||
{
|
||||
Name: "orderCount",
|
||||
|
|
|
@ -14,17 +14,17 @@ var (
|
|||
idField = code.StructField{
|
||||
Name: "ID",
|
||||
Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"},
|
||||
Tags: map[string][]string{"bson": {"_id", "omitempty"}},
|
||||
Tag: `bson:"_id,omitempty"`,
|
||||
}
|
||||
genderField = code.StructField{
|
||||
Name: "Gender",
|
||||
Type: code.SimpleType("Gender"),
|
||||
Tags: map[string][]string{"bson": {"gender"}},
|
||||
Tag: `bson:"gender"`,
|
||||
}
|
||||
ageField = code.StructField{
|
||||
Name: "Age",
|
||||
Type: code.TypeInt,
|
||||
Tags: map[string][]string{"bson": {"age"}},
|
||||
Tag: `bson:"age"`,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -36,7 +36,7 @@ func TestGenerateMongoRepository(t *testing.T) {
|
|||
code.StructField{
|
||||
Name: "Username",
|
||||
Type: code.TypeString,
|
||||
Tags: map[string][]string{"bson": {"username"}},
|
||||
Tag: `bson:"username"`,
|
||||
},
|
||||
genderField,
|
||||
ageField,
|
||||
|
|
|
@ -63,12 +63,13 @@ func (g baseMethodGenerator) bsonFieldReference(fieldReference spec.FieldReferen
|
|||
}
|
||||
|
||||
func (g baseMethodGenerator) bsonTagFromField(field code.StructField) (string, error) {
|
||||
bsonTag, ok := field.Tags["bson"]
|
||||
bsonTag, ok := field.Tag.Lookup("bson")
|
||||
if !ok {
|
||||
return "", NewBsonTagNotFoundError(field.Name)
|
||||
}
|
||||
|
||||
return bsonTag[0], nil
|
||||
documentKey := strings.Split(bsonTag, ",")[0]
|
||||
return documentKey, nil
|
||||
}
|
||||
|
||||
func (g baseMethodGenerator) convertQuerySpec(query spec.QuerySpec) (querySpec, error) {
|
||||
|
|
|
@ -15,37 +15,37 @@ var (
|
|||
idField = code.StructField{
|
||||
Name: "ID",
|
||||
Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"},
|
||||
Tags: map[string][]string{"bson": {"_id", "omitempty"}},
|
||||
Tag: `bson:"_id,omitempty"`,
|
||||
}
|
||||
genderField = code.StructField{
|
||||
Name: "Gender",
|
||||
Type: code.SimpleType("Gender"),
|
||||
Tags: map[string][]string{"bson": {"gender"}},
|
||||
Tag: `bson:"gender"`,
|
||||
}
|
||||
ageField = code.StructField{
|
||||
Name: "Age",
|
||||
Type: code.TypeInt,
|
||||
Tags: map[string][]string{"bson": {"age"}},
|
||||
Tag: `bson:"age"`,
|
||||
}
|
||||
nameField = code.StructField{
|
||||
Name: "Name",
|
||||
Type: code.SimpleType("NameModel"),
|
||||
Tags: map[string][]string{"bson": {"name"}},
|
||||
Tag: `bson:"name"`,
|
||||
}
|
||||
referrerField = code.StructField{
|
||||
Name: "Referrer",
|
||||
Type: code.PointerType{ContainedType: code.SimpleType("UserModel")},
|
||||
Tags: map[string][]string{"bson": {"referrer"}},
|
||||
Tag: `bson:"referrer"`,
|
||||
}
|
||||
consentHistoryField = code.StructField{
|
||||
Name: "ConsentHistory",
|
||||
Type: code.ArrayType{ContainedType: code.SimpleType("ConsentHistory")},
|
||||
Tags: map[string][]string{"bson": {"consent_history"}},
|
||||
Tag: `bson:"consent_history"`,
|
||||
}
|
||||
enabledField = code.StructField{
|
||||
Name: "Enabled",
|
||||
Type: code.TypeBool,
|
||||
Tags: map[string][]string{"bson": {"enabled"}},
|
||||
Tag: `bson:"enabled"`,
|
||||
}
|
||||
accessTokenField = code.StructField{
|
||||
Name: "AccessToken",
|
||||
|
@ -55,7 +55,7 @@ var (
|
|||
firstNameField = code.StructField{
|
||||
Name: "First",
|
||||
Type: code.TypeString,
|
||||
Tags: map[string][]string{"bson": {"first"}},
|
||||
Tag: `bson:"first"`,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -66,7 +66,7 @@ var userModel = code.Struct{
|
|||
code.StructField{
|
||||
Name: "Username",
|
||||
Type: code.TypeString,
|
||||
Tags: map[string][]string{"bson": {"username"}},
|
||||
Tag: `bson:"username"`,
|
||||
},
|
||||
genderField,
|
||||
ageField,
|
||||
|
|
Loading…
Reference in a new issue