-
Notifications
You must be signed in to change notification settings - Fork 882
Add support for omitempty in JSON tags #3117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Adds a new configuration option json_tags_omit_empty
2ee0f0c
to
81dd475
Compare
What's the progress on this? Is this PR just waiting for a review? |
Thoughts on an option for setting |
Is there an updated status here? Seems like a good fix |
I don't know if the quality of the code is good, but this feature looks valuable. Reusing the sqlc-generated structs would be great. If they can be extended in any way via config options like this one, it makes them versitile. |
I'd like to have this feature as well |
Any update on merging it? There does not seem to be any interaction from contributors in this PR |
@kyleconroy could you please have a look over this PR? |
looking forward to this PR being closed👍🏽 |
For those waiting for this feature - a workaround is to run this after SQLC has done generating. A parse is performed of the given file and The script was hacked up without much care so take it as a word of warning if it does not work for your edge case. package main
import (
"bytes"
"go/ast"
"go/format"
"go/parser"
"go/token"
"log"
"os"
"strings"
)
const filePath = "./src/data/models.go"
func main() {
// Parse the source code
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments)
if err != nil {
log.Fatal(err)
}
// Modify the AST
ast.Inspect(f, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.StructType:
for _, field := range x.Fields.List {
if field.Tag == nil {
continue
}
if field.Tag.Value == "" || field.Tag.Kind != token.STRING {
continue
}
field.Tag.Value = modifyJSONTag(field.Tag.Value)
}
}
return true
})
// Write the output back to the original file
var buf bytes.Buffer
err = format.Node(&buf, fset, f)
if err != nil {
log.Fatal(err)
}
outputFile, err := os.Create(filePath)
if err != nil {
log.Fatal(err)
}
defer outputFile.Close()
_, err = outputFile.Write(buf.Bytes())
if err != nil {
log.Fatal(err)
}
}
func modifyJSONTag(tagValue string) string {
tagValue = strings.Trim(tagValue, "`")
tags := strings.Split(tagValue, " ")
var modifiedTags []string
for _, tag := range tags {
// Only modify JSON tags, leave others as they are.
if !strings.HasPrefix(tag, "json:") {
modifiedTags = append(modifiedTags, tag)
continue
}
jsonQuoted := tag[5:] // Remove "json:" prefix
jsonValue := strings.Trim(jsonQuoted, "\"") // Remove quotes
jsonOptions := strings.Split(jsonValue, ",") // Split options
// Check if "omitempty" is already present
hasOmitempty := false
for _, opt := range jsonOptions {
if opt == "omitempty" {
hasOmitempty = true
break
}
}
// Add "omitempty" if not present and the field is not ignored
if !hasOmitempty && jsonOptions[0] != "-" {
jsonOptions = append(jsonOptions, "omitempty")
}
// Reconstruct the JSON tag
newJSONTag := "json:\"" + strings.Join(jsonOptions, ",") + "\""
modifiedTags = append(modifiedTags, newJSONTag)
}
// Reconstruct the full tag
return "`" + strings.Join(modifiedTags, " ") + "`"
} |
Adds a new configuration option json_tags_omit_empty which adds
omitempty
to JSON tags.Closes #1098
Closes #1084
Related To:
#1132
#1087