Supports encoding of structure fields that should be ignored

This commit is contained in:
Masaaki Goshima 2020-04-21 13:38:48 +09:00
parent a573d86121
commit 37a7ac09ee
3 changed files with 28 additions and 17 deletions

View File

@ -186,6 +186,8 @@ func (e *Encoder) compile(v reflect.Value) (EncodeOp, error) {
return e.compileUint32() return e.compileUint32()
case reflect.Uint64: case reflect.Uint64:
return e.compileUint64() return e.compileUint64()
case reflect.Uintptr:
return e.compileUint()
case reflect.Float32: case reflect.Float32:
return e.compileFloat32() return e.compileFloat32()
case reflect.Float64: case reflect.Float64:
@ -196,20 +198,8 @@ func (e *Encoder) compile(v reflect.Value) (EncodeOp, error) {
return e.compileBool() return e.compileBool()
case reflect.Interface: case reflect.Interface:
return nil, ErrCompileSlowPath return nil, ErrCompileSlowPath
case reflect.Func:
return nil, nil
case reflect.Chan:
return nil, nil
case reflect.UnsafePointer:
return nil, nil
case reflect.Uintptr:
return nil, nil
case reflect.Complex64:
return nil, nil
case reflect.Complex128:
return nil, nil
} }
return nil, xerrors.Errorf("failed to compile %s: %w", v.Type(), ErrUnknownType) return nil, xerrors.Errorf("failed to encode type %s: %w", v.Type(), ErrUnsupportedType)
} }
func (e *Encoder) compilePtr(v reflect.Value) (EncodeOp, error) { func (e *Encoder) compilePtr(v reflect.Value) (EncodeOp, error) {
@ -336,14 +326,33 @@ func (e *Encoder) compileArray(v reflect.Value) (EncodeOp, error) {
}, nil }, nil
} }
func (e *Encoder) getTag(field reflect.StructField) string {
return field.Tag.Get("json")
}
func (e *Encoder) isIgnoredStructField(field reflect.StructField) bool {
if field.PkgPath != "" && !field.Anonymous {
// private field
return true
}
tag := e.getTag(field)
if tag == "-" {
return true
}
return false
}
func (e *Encoder) compileStruct(v reflect.Value) (EncodeOp, error) { func (e *Encoder) compileStruct(v reflect.Value) (EncodeOp, error) {
typ := v.Type() typ := v.Type()
fieldNum := typ.NumField() fieldNum := typ.NumField()
opQueue := make([]EncodeOp, 0, fieldNum) opQueue := make([]EncodeOp, 0, fieldNum)
for i := 0; i < fieldNum; i++ { for i := 0; i < fieldNum; i++ {
field := typ.Field(i) field := typ.Field(i)
if e.isIgnoredStructField(field) {
continue
}
keyName := field.Name keyName := field.Name
tag := field.Tag.Get("json") tag := e.getTag(field)
opts := strings.Split(tag, ",") opts := strings.Split(tag, ",")
if len(opts) > 0 { if len(opts) > 0 {
if opts[0] != "" { if opts[0] != "" {

View File

@ -96,6 +96,8 @@ func Test_Encoder(t *testing.T) {
A int `json:"a"` A int `json:"a"`
B uint `json:"b"` B uint `json:"b"`
C string `json:"c"` C string `json:"c"`
D int `json:"-"` // ignore field
a int `json:"aa"` // private field
}{ }{
A: -1, A: -1,
B: 1, B: 1,

View File

@ -1,8 +1,8 @@
package json package json
import "errors" import "golang.org/x/xerrors"
var ( var (
ErrUnknownType = errors.New("unknown type name") ErrUnsupportedType = xerrors.New("json: unsupported type")
ErrCompileSlowPath = errors.New("detect dynamic type ( interface{} ) and compile with slow path") ErrCompileSlowPath = xerrors.New("json: detect dynamic type ( interface{} ) and compile with slow path")
) )