Skip to content

Commit

Permalink
Rename 'custom' as 'extended'.
Browse files Browse the repository at this point in the history
Refs #586
  • Loading branch information
echlebek committed Nov 22, 2017
1 parent df2f7d0 commit 5640e85
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 44 deletions.
46 changes: 23 additions & 23 deletions types/dynamic/dynamic.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ import (
jsoniter "github.com/json-iterator/go"
)

// CustomAttributer is for use with GetField. It allows GetField to access
// serialized custom attributes.
type CustomAttributer interface {
// CustomAttributes returns json-serialized custom attributes.
CustomAttributes() []byte
// ExtendedAttributer is for use with GetField. It allows GetField to access
// serialized extended attributes.
type ExtendedAttributer interface {
// ExtendedAttributes returns json-serialized extended attributes.
ExtendedAttributes() []byte
}

// GetField gets a field from v according to its name.
// If GetField doesn't find a struct field with the corresponding name, then
// it will try to dynamically find the corresponding item in the 'Custom'
// field. GetField is case-sensitive, but custom attribute names will be
// it will try to dynamically find the corresponding item in the 'Extended'
// field. GetField is case-sensitive, but extended attribute names will be
// converted to CamelCaps.
func GetField(v CustomAttributer, name string) (interface{}, error) {
func GetField(v ExtendedAttributer, name string) (interface{}, error) {
strukt := reflect.Indirect(reflect.ValueOf(v))
if kind := strukt.Kind(); kind != reflect.Struct {
return nil, fmt.Errorf("invalid type (want struct): %v", kind)
Expand All @@ -31,19 +31,19 @@ func GetField(v CustomAttributer, name string) (interface{}, error) {
if ok {
return field.Value.Interface(), nil
}
// If we get here, we are dealing with custom attributes.
return getCustomAttribute(v.CustomAttributes(), name)
// If we get here, we are dealing with extended attributes.
return getExtendedAttribute(v.ExtendedAttributes(), name)
}

// getCustomAttribute dynamically builds a concrete type. If the concrete
// getExtendedAttribute dynamically builds a concrete type. If the concrete
// type is a composite type, then it will either be a struct or a slice.
func getCustomAttribute(msg []byte, name string) (interface{}, error) {
func getExtendedAttribute(msg []byte, name string) (interface{}, error) {
any := jsoniter.Get(msg, name)
if err := any.LastError(); err != nil {
lowerName := fmt.Sprintf("%s%s", strings.ToLower(string(name[0])), name[1:])
if name != lowerName {
// fall back to lower-case name
return getCustomAttribute(msg, lowerName)
return getExtendedAttribute(msg, lowerName)
}
return nil, err
}
Expand Down Expand Up @@ -189,10 +189,10 @@ func getJSONFields(v reflect.Value) map[string]structField {
return result
}

// ExtractCustomAttributes selects only custom attributes from msg. It will
// ExtractExtendedAttributes selects only extended attributes from msg. It will
// ignore any fields in msg that correspond to fields in v. v must be of kind
// reflect.Struct.
func ExtractCustomAttributes(v interface{}, msg []byte) ([]byte, error) {
func ExtractExtendedAttributes(v interface{}, msg []byte) ([]byte, error) {
strukt := reflect.Indirect(reflect.ValueOf(v))
if kind := strukt.Kind(); kind != reflect.Struct {
return nil, fmt.Errorf("invalid type (want struct): %v", kind)
Expand All @@ -207,7 +207,7 @@ func ExtractCustomAttributes(v interface{}, msg []byte) ([]byte, error) {
for _, any := range sortAnys(anys) {
_, ok := fields[any.Name]
if ok {
// Not a custom attribute
// Not a extended attribute
continue
}
if !objectStarted {
Expand All @@ -227,20 +227,20 @@ func ExtractCustomAttributes(v interface{}, msg []byte) ([]byte, error) {
}

// Marshal encodes the struct fields in v that are valid to encode.
// It also encodes any custom attributes that are defined. Marshal
// It also encodes any extended attributes that are defined. Marshal
// respects the encoding/json rules regarding exported fields, and tag
// semantics. If v's kind is not reflect.Struct, an error will be returned.
func Marshal(v CustomAttributer) ([]byte, error) {
func Marshal(v ExtendedAttributer) ([]byte, error) {
s := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 4096)
s.WriteObjectStart()

if err := encodeStructFields(v, s); err != nil {
return nil, err
}

custom := v.CustomAttributes()
if len(custom) > 0 {
if err := encodeCustomFields(custom, s); err != nil {
extended := v.ExtendedAttributes()
if len(extended) > 0 {
if err := encodeExtendedFields(extended, s); err != nil {
return nil, err
}
}
Expand Down Expand Up @@ -292,9 +292,9 @@ func sortAnys(m map[string]jsoniter.Any) []anyT {
return anys
}

func encodeCustomFields(custom []byte, s *jsoniter.Stream) error {
func encodeExtendedFields(extended []byte, s *jsoniter.Stream) error {
var anys map[string]jsoniter.Any
if err := jsoniter.Unmarshal(custom, &anys); err != nil {
if err := jsoniter.Unmarshal(extended, &anys); err != nil {
return err
}
for _, any := range sortAnys(anys) {
Expand Down
42 changes: 21 additions & 21 deletions types/dynamic/dynamic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ type MyType struct {
Foo string `json:"foo"`
Bar []MyType `json:"bar"`

custom []byte
extended []byte
}

func (m MyType) CustomAttributes() []byte {
return m.custom
func (m MyType) ExtendedAttributes() []byte {
return m.extended
}

func (m MyType) Get(name string) (interface{}, error) {
Expand All @@ -106,48 +106,48 @@ func (m *MyType) UnmarshalJSON(p []byte) error {
return err
}
*m = MyType(x)
custom, err := ExtractCustomAttributes(m, p)
extended, err := ExtractExtendedAttributes(m, p)
if err != nil {
return err
}
m.custom = custom
m.extended = extended
return nil
}

func TestExtractEmptyCustomAttributes(t *testing.T) {
func TestExtractEmptyExtendedAttributes(t *testing.T) {
require := require.New(t)
assert := assert.New(t)

msg := []byte(`{"foo": "hello, world!","bar":[{"foo":"o hai"}]}`)
var m MyType

attrs, err := ExtractCustomAttributes(m, msg)
attrs, err := ExtractExtendedAttributes(m, msg)
require.Nil(err)
assert.Equal([]byte("{}"), attrs)
}

func TestExtractCustomAttributes(t *testing.T) {
func TestExtractExtendedAttributes(t *testing.T) {
require := require.New(t)
assert := assert.New(t)

msg := []byte(`{"foo": "hello, world!","bar":[{"foo":"o hai"}], "customattr": "such custom"}`)
msg := []byte(`{"foo": "hello, world!","bar":[{"foo":"o hai"}], "extendedattr": "such extended"}`)
var m MyType

attrs, err := ExtractCustomAttributes(m, msg)
attrs, err := ExtractExtendedAttributes(m, msg)
require.Nil(err)
assert.Equal([]byte(`{"customattr":"such custom"}`), attrs)
assert.Equal([]byte(`{"extendedattr":"such extended"}`), attrs)
}

func TestMarshal(t *testing.T) {
require := require.New(t)
assert := assert.New(t)
customBytes := []byte(`{"a":1,"b":2.0,"c":true,"d":"false","e":[1,2,3],"f":{"foo":"bar"}}`)
extendedBytes := []byte(`{"a":1,"b":2.0,"c":true,"d":"false","e":[1,2,3],"f":{"foo":"bar"}}`)
expBytes := []byte(`{"bar":null,"foo":"hello world!","a":1,"b":2.0,"c":true,"d":"false","e":[1,2,3],"f":{"foo":"bar"}}`)

m := MyType{
Foo: "hello world!",
Bar: nil,
custom: customBytes,
Foo: "hello world!",
Bar: nil,
extended: extendedBytes,
}

b, err := Marshal(m)
Expand All @@ -157,9 +157,9 @@ func TestMarshal(t *testing.T) {

func TestGetField(t *testing.T) {
m := MyType{
Foo: "hello",
Bar: []MyType{{Foo: "there"}},
custom: []byte(`{"a":"a","b":1,"c":2.0,"d":true,"e":null,"foo":{"hello":5},"bar":[true,10.5]}`),
Foo: "hello",
Bar: []MyType{{Foo: "there"}},
extended: []byte(`{"a":"a","b":1,"c":2.0,"d":true,"e":null,"foo":{"hello":5},"bar":[true,10.5]}`),
}

tests := []struct {
Expand Down Expand Up @@ -218,7 +218,7 @@ func TestGetField(t *testing.T) {

func TestQueryGovaluateSimple(t *testing.T) {
m := MyType{
custom: []byte(`{"hello":5}`),
extended: []byte(`{"hello":5}`),
}

expr, err := govaluate.NewEvaluableExpression("hello == 5")
Expand All @@ -240,7 +240,7 @@ func TestQueryGovaluateSimple(t *testing.T) {

func TestQueryGovaluateComplex(t *testing.T) {
m := MyType{
custom: []byte(`{"hello":{"foo":5,"bar":6.0}}`),
extended: []byte(`{"hello":{"foo":5,"bar":6.0}}`),
}

expr, err := govaluate.NewEvaluableExpression("hello.Foo == 5")
Expand Down Expand Up @@ -273,7 +273,7 @@ func TestMarshalUnmarshal(t *testing.T) {
var m MyType
err := json.Unmarshal(data, &m)
require.Nil(t, err)
assert.Equal(t, MyType{Foo: "hello", custom: []byte(`{"a":10,"b":"c"}`)}, m)
assert.Equal(t, MyType{Foo: "hello", extended: []byte(`{"a":10,"b":"c"}`)}, m)
b, err := json.Marshal(m)
require.Nil(t, err)
assert.Equal(t, data, b)
Expand Down

0 comments on commit 5640e85

Please sign in to comment.