Browse Source

codec: change signature to MissingFielder interface

Change CodecMissingFields() method of the interface
to return a map[string]interface{}, not a slice of struct {string; interface{}}

This ensures that there is only one entry for each field name, and that
we do not introduce more custom types in the signature.

Updates #258
Ugorji Nwoke 7 years ago
parent
commit
99ea80c8b1
3 changed files with 12 additions and 20 deletions
  1. 9 11
      codec/encode.go
  2. 1 7
      codec/helper.go
  3. 2 2
      codec/values_test.go

+ 9 - 11
codec/encode.go

@@ -570,7 +570,7 @@ func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
 	tisfi := fti.sfiSrc
 	var newlen int
 	toMap := !(fti.toArray || e.h.StructToArray)
-	var mf []MissingFieldPair
+	var mf map[string]interface{}
 	if f.ti.mf {
 		mf = rv2i(rv).(MissingFielder).CodecMissingFields()
 		toMap = true
@@ -656,12 +656,13 @@ func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
 	}
 
 	var mflen int
-	for i := range mf {
-		if mf[i].Field == "" {
+	for k, v := range mf {
+		if k == "" {
+			delete(mf, k)
 			continue
 		}
-		if fti.infoFieldOmitempty && isEmptyValue(reflect.ValueOf(mf[i].Value), e.h.TypeInfos, recur, recur) {
-			mf[i].Field = ""
+		if fti.infoFieldOmitempty && isEmptyValue(reflect.ValueOf(v), e.h.TypeInfos, recur, recur) {
+			delete(mf, k)
 			continue
 		}
 		mflen++
@@ -687,14 +688,11 @@ func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
 			}
 		}
 		// now, add the others
-		for i := range mf {
-			if mf[i].Field == "" {
-				continue
-			}
+		for k, v := range mf {
 			ee.WriteMapElemKey()
-			e.kStructFieldKeyName(fti.keyType, mf[i].Field)
+			e.kStructFieldKeyName(fti.keyType, k)
 			ee.WriteMapElemValue()
-			e.encode(mf[i].Value)
+			e.encode(v)
 		}
 		ee.WriteMapEnd()
 	} else {

+ 1 - 7
codec/helper.go

@@ -427,12 +427,6 @@ type Selfer interface {
 	CodecDecodeSelf(*Decoder)
 }
 
-// MissingFieldPair is a convenience value composed of the field name and the value of the field.
-type MissingFieldPair struct {
-	Field string
-	Value interface{}
-}
-
 // MissingFielder defines the interface allowing structs to internally decode or encode
 // values which do not map to struct fields.
 //
@@ -449,7 +443,7 @@ type MissingFielder interface {
 	CodecMissingField(field []byte, value interface{}) bool
 
 	// CodecMissingFields returns the set of fields which are not struct fields
-	CodecMissingFields() []MissingFieldPair
+	CodecMissingFields() map[string]interface{}
 }
 
 // MapBySlice is a tag interface that denotes wrapped slice should encode as a map in the stream.

+ 2 - 2
codec/values_test.go

@@ -57,8 +57,8 @@ func (t *missingFielderT1) CodecMissingField(field []byte, value interface{}) bo
 	return true
 }
 
-func (t *missingFielderT1) CodecMissingFields() []MissingFieldPair {
-	return []MissingFieldPair{{"F", t.f}, {"I", t.i}}
+func (t *missingFielderT1) CodecMissingFields() map[string]interface{} {
+	return map[string]interface{}{"F": t.f, "I": t.i}
 }
 
 type missingFielderT2 struct {