Skip to content

Commit

Permalink
Fix pointer marshal
Browse files Browse the repository at this point in the history
  • Loading branch information
alecsammon authored and mweibel committed Oct 3, 2024
1 parent 80f0f5c commit 3854dcf
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
11 changes: 11 additions & 0 deletions sheriff.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,21 @@ func marshalValue(options *Options, v reflect.Value) (interface{}, error) {
// types which are e.g. structs, slices or maps and implement one of the following interfaces should not be
// marshalled by sheriff because they'll be correctly marshalled by json.Marshal instead.
// Otherwise (e.g. net.IP) a byte slice may be output as a list of uints instead of as an IP string.
// This needs to be checked for both value and pointer types.
switch val.(type) {
case json.Marshaler, encoding.TextMarshaler, fmt.Stringer:
return val, nil
}

if v.CanAddr() {
addrVal := v.Addr().Interface()

switch addrVal.(type) {
case json.Marshaler, encoding.TextMarshaler, fmt.Stringer:
return addrVal, nil
}
}

k := v.Kind()

switch k {
Expand Down
35 changes: 35 additions & 0 deletions sheriff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sheriff

import (
"encoding/json"
"fmt"
"net"
"reflect"
"testing"
Expand Down Expand Up @@ -583,16 +584,48 @@ type TestMarshal_NamedEmbedded struct {
Qux string `json:"qux" groups:"test"`
}

// TestMarshal_EmbeddedCustom is used to test an embedded struct with a custom marshaler that is not a pointer.
type TestMarshal_EmbeddedCustom struct {
Val int
Set bool
}

func (t TestMarshal_EmbeddedCustom) MarshalJSON() ([]byte, error) {
if t.Set {
return []byte(fmt.Sprintf("%d", t.Val)), nil
}

return nil, nil
}

// TestMarshal_EmbeddedCustomPtr is used to test an embedded struct with a custom marshaler that is a pointer.
type TestMarshal_EmbeddedCustomPtr struct {
Val int
Set bool
}

func (t *TestMarshal_EmbeddedCustomPtr) MarshalJSON() ([]byte, error) {
if t.Set {
return []byte(fmt.Sprintf("%d", t.Val)), nil
}

return nil, nil
}

type TestMarshal_EmbeddedParent struct {
*TestMarshal_Embedded
*TestMarshal_NamedEmbedded `json:"embedded"`
*TestMarshal_EmbeddedCustom `json:"value"`
*TestMarshal_EmbeddedCustomPtr `json:"value_ptr"`
Bar string `json:"bar" groups:"test"`
}

func TestMarshal_EmbeddedField(t *testing.T) {
v := TestMarshal_EmbeddedParent{
&TestMarshal_Embedded{"Hello"},
&TestMarshal_NamedEmbedded{"Big"},
&TestMarshal_EmbeddedCustom{10, true},
&TestMarshal_EmbeddedCustomPtr{20, true},
"World",
}
o := &Options{Groups: []string{"test"}}
Expand All @@ -614,6 +647,8 @@ func TestMarshal_EmbeddedField(t *testing.T) {
expectedMap, err := json.Marshal(map[string]interface{}{
"bar": "World",
"foo": "Hello",
"value": 10,
"value_ptr": 20,
"embedded": map[string]interface{}{
"qux": "Big",
},
Expand Down

0 comments on commit 3854dcf

Please sign in to comment.