Skip to content

Commit

Permalink
Merge pull request #13 from alehechka/feature/omitempty-arg
Browse files Browse the repository at this point in the history
Add OmitEmpty option for tag generation
  • Loading branch information
alehechka authored Jul 4, 2022
2 parents ac6911f + 640414b commit 678661f
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 10 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ json2go generate --url="https://gorest.co.in/public/v2/users"
| Package Name | `--package=api` | `string` | Name of package to generate types into. A nested package path is valid | `main` |
| Output File Name | `--output` | `string` | The name of the file that is generated. If a file is provided as input, will use matching name unless explicitly provided. The ".go" extension is not required and will be automatically appended. | `types.go` |
| Time Format | `--time=2006-01-02` | `string` | Time format to use while parsing strings for potential time.Time variables. View time.Time constants for possible defaults: https://pkg.go.dev/time#pkg-constants | `RFC3339` |
| Omit Empty | `--omitempty` | `bool` | Appends the omitempty to all object variable tags. | `false` |
| Debug logging | `--debug` | `bool` | Will output debugging console logs. | `false` |
| Quiet | `--quiet` | `bool` | Will quiet fatal errors. | `false` |
| STDOUT | `--out` | `bool` | Instead of generating a Go file, will instead print the contents to STDOUT | `false` |
Expand Down
6 changes: 6 additions & 0 deletions cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const (
quietFlag = "quiet"
stdoutFlag = "out"
timeFormatFlag = "time"
omitEmptyFlag = "omitempty"
)

var generateFlags = []cli.Flag{
Expand Down Expand Up @@ -57,6 +58,10 @@ var generateFlags = []cli.Flag{
Usage: "Time format to use while parsing strings for potential time.Time variables. View time.Time constants for possible defaults: https://pkg.go.dev/time#pkg-constants",
Value: time.RFC3339,
},
&cli.BoolFlag{
Name: omitEmptyFlag,
Usage: "Appends the omitempty to all object variable tags.",
},
&cli.BoolFlag{
Name: debugFlag,
Usage: "Log debug messages.",
Expand Down Expand Up @@ -87,6 +92,7 @@ func generateTypes(ctx *cli.Context) (err error) {
PackageName: ctx.String(packageFlag),
OutputFileName: ctx.String(outputFileFlag),
TimeFormat: ctx.String(timeFormatFlag),
OmitEmpty: ctx.Bool(omitEmptyFlag),
}

if ctx.Bool(stdoutFlag) {
Expand Down
2 changes: 2 additions & 0 deletions gen/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Config struct {
PackageName string
OutputFileName string
TimeFormat string
OmitEmpty bool
}

func (c *Config) toJensharedConfig() *jenshared.Config {
Expand All @@ -37,6 +38,7 @@ func (c *Config) toJensharedConfig() *jenshared.Config {
OutputFileName: c.OutputFileName,
OutputDirectory: dir,
TimeFormat: c.getTimeFormat(),
OmitEmpty: c.OmitEmpty,
Debugger: c.Debugger,
}
}
Expand Down
5 changes: 2 additions & 3 deletions jenshared/addStructs.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ func createStructItem(item TypeItem) jen.Code {
s.Id(item.Type)
}

if item.Name != "" {
s.Tag(map[string]string{"json": item.Name})
}
s.Tag(item.Tags())

return s
}
10 changes: 5 additions & 5 deletions jenshared/addStructsFromJSON.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func createTypeItemsMapFromJSON(data interface{}, config *Config) TypeItemsMap {
func parseInterface(items TypeItemsMap, data interface{}, config *Config) TypeItemsMap {
switch concreteVal := data.(type) {
case bool, float64, string:
items[config.RootName] = TypeItems{{Name: config.RootName, Type: inferDataType(concreteVal, config)}}
items[config.RootName] = TypeItems{{Name: config.RootName, Type: inferDataType(concreteVal, config), OmitEmpty: config.OmitEmpty}}
case map[string]interface{}:
parseMap(items, concreteVal, config.RootName, config)
case []interface{}:
Expand All @@ -37,10 +37,10 @@ func diveTopLevelArray(items TypeItemsMap, data []interface{}, config *Config, a
if len(data) > 0 {
switch firstVal := data[0].(type) {
case bool, float64, string:
items[config.RootName] = TypeItems{{Name: config.RootName, Type: fmt.Sprintf("%s%s", acc, inferDataType(firstVal, config))}}
items[config.RootName] = TypeItems{{Name: config.RootName, Type: fmt.Sprintf("%s%s", acc, inferDataType(firstVal, config)), OmitEmpty: config.OmitEmpty}}
case map[string]interface{}:
arrTitle := fmt.Sprintf("%sArray", config.RootName)
items[arrTitle] = TypeItems{{Name: arrTitle, Type: fmt.Sprintf("%s%s", acc, config.RootName)}}
items[arrTitle] = TypeItems{{Name: arrTitle, Type: fmt.Sprintf("%s%s", acc, config.RootName), OmitEmpty: config.OmitEmpty}}
parseMap(items, firstVal, config.RootName, config)

case []interface{}:
Expand All @@ -60,10 +60,10 @@ func parseMap(items TypeItemsMap, data map[string]interface{}, parent string, co
items[parent] = append(items[parent], TypeItem{Name: key, Type: title})
parseMap(items, concreteVal, title, config)
case []interface{}:
items[parent] = append(items[parent], TypeItem{Name: key, Type: fmt.Sprintf("[]%s", title)})
items[parent] = append(items[parent], TypeItem{Name: key, Type: fmt.Sprintf("[]%s", title), OmitEmpty: config.OmitEmpty})
parseFirstIndexArray(items, concreteVal, title, config)
default:
items[parent] = append(items[parent], TypeItem{Name: key, Type: inferDataType(concreteVal, config)})
items[parent] = append(items[parent], TypeItem{Name: key, Type: inferDataType(concreteVal, config), OmitEmpty: config.OmitEmpty})
}
}
return items
Expand Down
21 changes: 19 additions & 2 deletions jenshared/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ type Config struct {
OutputFileName string
OutputDirectory string
TimeFormat string
OmitEmpty bool
Debugger *log.Logger
}

// TypeItem represents a parsed JSON variable
type TypeItem struct {
Name string
Type string
Name string
Type string
OmitEmpty bool
}

// Title converts the JSON name to TitleCase
Expand All @@ -35,6 +37,21 @@ func (t TypeItem) Title() string {
return strings.Title(str)
}

// TagJSON prepares the tag for provided item
func (t TypeItem) TagJSON() string {
tags := []string{t.Name}
if t.OmitEmpty {
tags = append(tags, "omitempty")
}

return strings.Join(tags, ",")
}

// Tags creates tha Tags map
func (t TypeItem) Tags() map[string]string {
return map[string]string{"json": t.TagJSON()}
}

// TypeItems is an array of TypeItem objects
type TypeItems []TypeItem

Expand Down

0 comments on commit 678661f

Please sign in to comment.