Skip to content

Commit

Permalink
Don't parse struct field type if it's omitted from JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
VojtechVitek committed Aug 28, 2023
1 parent b2bdccc commit b761d1a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 36 deletions.
2 changes: 2 additions & 0 deletions internal/parser/regex.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type JsonTag struct {
Value string
IsString bool
Omitempty bool
Inline bool
}

func GetJsonTag(structTags string) (JsonTag, bool) {
Expand All @@ -41,6 +42,7 @@ func GetJsonTag(structTags string) (JsonTag, bool) {
Value: submatches[1] + submatches[2],
IsString: strings.Contains(submatches[2], ",string"),
Omitempty: strings.Contains(submatches[2], ",omitempty"),
Inline: strings.Contains(submatches[2], ",inline"),
}

return jsonTag, true
Expand Down
71 changes: 35 additions & 36 deletions internal/parser/struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package parser
import (
"fmt"
"go/types"
"strings"

"github.com/webrpc/webrpc/schema"
)
Expand All @@ -21,7 +20,12 @@ func (p *Parser) ParseStruct(typeName string, structTyp *types.Struct) (*schema.
}
structTags := structTyp.Tag(i)

if structField.Embedded() || strings.Contains(structTags, `json:",inline"`) {
jsonTag, _ := GetJsonTag(structTags)
if jsonTag.Name == "-" { // struct field ignored by `json:"-"` struct tag
continue
}

if structField.Embedded() || jsonTag.Inline {
varType, err := p.ParseNamedType("", structField.Type())
if err != nil {
return nil, fmt.Errorf("parsing var %v: %w", structField.Name(), err)
Expand All @@ -35,7 +39,7 @@ func (p *Parser) ParseStruct(typeName string, structTyp *types.Struct) (*schema.
continue
}

field, err := p.parseStructField(typeName+"Field", structField, structTags)
field, err := p.parseStructField(typeName+"Field", structField, jsonTag)
if err != nil {
return nil, fmt.Errorf("parsing struct field %v: %w", i, err)
}
Expand All @@ -58,7 +62,7 @@ func (p *Parser) ParseStruct(typeName string, structTyp *types.Struct) (*schema.

// parses single Go struct field
// if the field is embedded, ie. `json:",inline"`, parse recursively
func (p *Parser) parseStructField(structTypeName string, field *types.Var, structTags string) (*schema.TypeField, error) {
func (p *Parser) parseStructField(structTypeName string, field *types.Var, jsonTag JsonTag) (*schema.TypeField, error) {
fieldName := field.Name()
fieldType := field.Type()

Expand All @@ -68,48 +72,43 @@ func (p *Parser) parseStructField(structTypeName string, field *types.Var, struc

goFieldImport := p.GoTypeImport(fieldType)

jsonTag, ok := GetJsonTag(structTags)
if ok {
if jsonTag.Name != "" {
if jsonTag.Name == "-" { // struct field ignored by `json:"-"` struct tag
return nil, nil
}
jsonFieldName = jsonTag.Name
}

if jsonTag.Name != "" {
jsonFieldName = jsonTag.Name
}

if jsonTag.Omitempty {
optional = jsonTag.Omitempty
if optional {
goFieldType = "*" + goFieldType
}

if jsonTag.IsString { // struct field forced to be string by `json:",string"`
goFieldType = "*" + goFieldType
}

structField := &schema.TypeField{
Name: jsonFieldName,
Type: &schema.VarType{
Expr: "string",
Type: schema.T_String,
},
TypeExtra: schema.TypeExtra{
Meta: []schema.TypeFieldMeta{
{"go.field.name": fieldName},
{"go.field.type": goFieldType},
},
Optional: optional,
if jsonTag.IsString { // struct field forced to be string by `json:",string"`
structField := &schema.TypeField{
Name: jsonFieldName,
Type: &schema.VarType{
Expr: "string",
Type: schema.T_String,
},
TypeExtra: schema.TypeExtra{
Meta: []schema.TypeFieldMeta{
{"go.field.name": fieldName},
{"go.field.type": goFieldType},
},
}
if goFieldImport != "" {
structField.TypeExtra.Meta = append(structField.TypeExtra.Meta,
schema.TypeFieldMeta{"go.type.import": goFieldImport},
)
}
Optional: optional,
},
}
if goFieldImport != "" {
structField.TypeExtra.Meta = append(structField.TypeExtra.Meta,
schema.TypeFieldMeta{"go.tag.json": jsonTag.Value},
schema.TypeFieldMeta{"go.type.import": goFieldImport},
)

return structField, nil
}
structField.TypeExtra.Meta = append(structField.TypeExtra.Meta,
schema.TypeFieldMeta{"go.tag.json": jsonTag.Value},
)

return structField, nil
}

if _, ok := field.Type().Underlying().(*types.Pointer); ok {
Expand Down

0 comments on commit b761d1a

Please sign in to comment.