Skip to content

Commit

Permalink
fix: support string tag opt
Browse files Browse the repository at this point in the history
fixes #36
  • Loading branch information
mweibel committed Mar 6, 2024
1 parent 22ec9d5 commit 8702425
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 11 deletions.
15 changes: 15 additions & 0 deletions sheriff.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ func Marshal(options *Options, data interface{}) (interface{}, error) {
continue
}

quoted := false
if jsonOpts.Contains("string") {
switch val.Kind() {
case reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
reflect.Float32, reflect.Float64,
reflect.String:
quoted = true
}
}

// if there is an anonymous field which is a struct
// we want the childs exposed at the toplevel to be
// consistent with the embedded json marshaller
Expand Down Expand Up @@ -179,6 +191,9 @@ func Marshal(options *Options, data interface{}) (interface{}, error) {
if err != nil {
return nil, err
}
if quoted {
v = fmt.Sprintf("%v", v)
}

// when a composition field we want to bring the child
// nodes to the top
Expand Down
23 changes: 23 additions & 0 deletions sheriff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -754,3 +754,26 @@ func TestMarshal_NilPointer(t *testing.T) {
assert.Nil(t, v)
assert.NoError(t, err)
}

func TestMarshal_User(t *testing.T) {
type JsonStringTag struct {
Test int64 `json:"test,string"`
TestB bool `json:"testb,string"`
TestF float64 `json:"testf,string"`
TestS string `json:"tests,string"`
}
j := JsonStringTag{
Test: 12,
TestB: true,
TestF: 12.0,
TestS: "test",
}

v, err := Marshal(&Options{}, j)
assert.NoError(t, err)
assert.Equal(t, map[string]interface{}{"test": "12", "testb": "true", "testf": "12", "tests": "test"}, v)

d, err := json.Marshal(j)
assert.NoError(t, err)
assert.Equal(t, `{"test":"12","testb":"true","testf":"12","tests":"\"test\""}`, string(d))
}
16 changes: 5 additions & 11 deletions tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ type tagOptions string
// parseTag splits a struct field's json tag into its name and
// comma-separated options.
func parseTag(tag string) (string, tagOptions) {
if idx := strings.Index(tag, ","); idx != -1 {
return tag[:idx], tagOptions(tag[idx+1:])
}
return tag, tagOptions("")
tag, opt, _ := strings.Cut(tag, ",")
return tag, tagOptions(opt)
}

// Contains reports whether a comma-separated list of options
Expand All @@ -28,15 +26,11 @@ func (o tagOptions) Contains(optionName string) bool {
}
s := string(o)
for s != "" {
var next string
i := strings.Index(s, ",")
if i >= 0 {
s, next = s[:i], s[i+1:]
}
if s == optionName {
var name string
name, s, _ = strings.Cut(s, ",")
if name == optionName {
return true
}
s = next
}
return false
}

0 comments on commit 8702425

Please sign in to comment.