Skip to content

Commit

Permalink
feat(gogenerate): add optional fields in log with omitempty annotation
Browse files Browse the repository at this point in the history
Signed-off-by: T M Rezoan Tamal <[email protected]>
  • Loading branch information
iamrz1 committed Jan 22, 2025
1 parent 72886c6 commit 599b03a
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pkg/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ type HTTPRequest struct {
Endpoint string `log:"http.url_details.endpoint"`

// Route is the URL path without interpolating the path variables.
Route string `log:"http.route"`
Route string `log:"http.route,omitempty"`
}

// FillFieldsFromRequest fills in the standard request fields
Expand Down
29 changes: 29 additions & 0 deletions tools/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ if s.{{.name}} != nil {
}`
)

const (
tagOmitEmpty = ",omitempty"
)

func main() {
flag.Usage = usage

Expand Down Expand Up @@ -140,6 +144,9 @@ func processStruct(w io.Writer, s *types.Struct, name string) {
write(w, nestedNilableMarshalerFormat, args)
case field == ".":
write(w, nestedMarshalerFormat, args)
case strings.HasSuffix(field, tagOmitEmpty):
args["key"] = strings.TrimSuffix(field, tagOmitEmpty)
write(w, getSimpleOptionalFieldFormat(s.Field(kk).Type()), args)
default:
write(w, simpleFieldFormat, args)
}
Expand Down Expand Up @@ -168,3 +175,25 @@ func usage() {
fmt.Fprintf(os.Stderr, "Flags:\n")
flag.PrintDefaults()
}

func getSimpleOptionalFieldFormat(p types.Type) string {
var defaultValue string
switch p.Underlying().String() {
case "string":
defaultValue = `""`
case "int", "int8", "int16", "int32", "int64",
"uint", "uint8", "uint16", "uint32", "uint64":
defaultValue = "0"
case "float32", "float64":
defaultValue = "0.0"
case "bool":
defaultValue = "false"
default:
defaultValue = "nil"
}

return fmt.Sprintf(`
if s.{{.name}} != %s {
addField("{{.key}}", s.{{.name}})
}`, defaultValue)
}
82 changes: 82 additions & 0 deletions tools/logger/logger_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package main

import (
"go/types"
"testing"
)

func TestGetSimpleOptionalFieldFormat(t *testing.T) {
newNamedType := func(name string, underlying types.Type) types.Type {
return types.NewNamed(
types.NewTypeName(0, nil, name, nil),
underlying,
nil,
)
}

tests := []struct {
name string
typ types.Type
expected string
}{
{
name: "string type",
typ: types.Typ[types.String],
expected: "\nif s.{{.name}} != \"\" {\n\taddField(\"{{.key}}\", s.{{.name}})\n}",
},
{
name: "int type",
typ: types.Typ[types.Int],
expected: "\nif s.{{.name}} != 0 {\n\taddField(\"{{.key}}\", s.{{.name}})\n}",
},
{
name: "float64 type",
typ: types.Typ[types.Float64],
expected: "\nif s.{{.name}} != 0.0 {\n\taddField(\"{{.key}}\", s.{{.name}})\n}",
},
{
name: "bool type",
typ: types.Typ[types.Bool],
expected: "\nif s.{{.name}} != false {\n\taddField(\"{{.key}}\", s.{{.name}})\n}",
},
{
name: "custom string type (type Token string)",
typ: newNamedType("Token", types.Typ[types.String]),
expected: "\nif s.{{.name}} != \"\" {\n\taddField(\"{{.key}}\", s.{{.name}})\n}",
},
{
name: "custom int type (type Digits int)",
typ: newNamedType("Digits", types.Typ[types.Int]),
expected: "\nif s.{{.name}} != 0 {\n\taddField(\"{{.key}}\", s.{{.name}})\n}",
},
{
name: "custom float type (type Decimal float64)",
typ: newNamedType("Decimal", types.Typ[types.Float64]),
expected: "\nif s.{{.name}} != 0.0 {\n\taddField(\"{{.key}}\", s.{{.name}})\n}",
},
{
name: "custom bool type (type Truther bool)",
typ: newNamedType("Truther", types.Typ[types.Bool]),
expected: "\nif s.{{.name}} != false {\n\taddField(\"{{.key}}\", s.{{.name}})\n}",
},
{
name: "pointer type",
typ: types.NewPointer(types.Typ[types.Int]),
expected: "\nif s.{{.name}} != nil {\n\taddField(\"{{.key}}\", s.{{.name}})\n}",
},
{
name: "pointer to custom type",
typ: types.NewPointer(newNamedType("Nullable", types.Typ[types.String])),
expected: "\nif s.{{.name}} != nil {\n\taddField(\"{{.key}}\", s.{{.name}})\n}",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := getSimpleOptionalFieldFormat(tt.typ)
if got != tt.expected {
t.Errorf("getSimpleOptionalFieldFormat() =\n%v\nwant:\n%v", got, tt.expected)
}
})
}
}

0 comments on commit 599b03a

Please sign in to comment.