diff --git a/encode_compile.go b/encode_compile.go index 9b91339..040e0be 100644 --- a/encode_compile.go +++ b/encode_compile.go @@ -542,8 +542,10 @@ func (e *Encoder) structHeader(fieldCode *structFieldCode, valueCode *opcode, ta switch op { case opStructFieldHead, opStructFieldHeadOmitEmpty, + opStructFieldHeadStringTag, opStructFieldHeadIndent, - opStructFieldHeadOmitEmptyIndent: + opStructFieldHeadOmitEmptyIndent, + opStructFieldHeadStringTagIndent: return valueCode.beforeLastCode() } return (*opcode)(unsafe.Pointer(fieldCode)) @@ -556,8 +558,10 @@ func (e *Encoder) structField(fieldCode *structFieldCode, valueCode *opcode, tag switch op { case opStructField, opStructFieldOmitEmpty, + opStructFieldStringTag, opStructFieldIndent, - opStructFieldOmitEmptyIndent: + opStructFieldOmitEmptyIndent, + opStructFieldStringTagIndent: return valueCode.beforeLastCode() } return code @@ -617,6 +621,16 @@ func (e *Encoder) compileStruct(typ *rtype, isPtr, root, withIndent bool) (*opco f = f.nextField.toStructFieldCode() } } + if fieldNum == 1 && valueCode.op == opPtr { + // if field number is one and primitive pointer type, + // it should encode as **not** pointer . + switch valueCode.next.op { + case opInt, opInt8, opInt16, opInt32, opInt64, + opUint, opUint8, opUint16, opUint32, opUint64, + opFloat32, opFloat64, opBool, opString, opBytes: + valueCode = valueCode.next + } + } key := fmt.Sprintf(`"%s":`, tag.key) fieldCode := &structFieldCode{ opcodeHeader: &opcodeHeader{ diff --git a/encode_test.go b/encode_test.go index 5c455f5..9fd5668 100644 --- a/encode_test.go +++ b/encode_test.go @@ -1132,3 +1132,29 @@ func TestEncodeBytekind(t *testing.T) { } } } + +// golang.org/issue/8582 +func TestEncodePointerString(t *testing.T) { + type stringPointer struct { + N *int64 `json:"n,string"` + } + var n int64 = 42 + b, err := json.Marshal(stringPointer{N: &n}) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + if got, want := string(b), `{"n":"42"}`; got != want { + t.Errorf("Marshal = %s, want %s", got, want) + } + var back stringPointer + err = json.Unmarshal(b, &back) + if err != nil { + t.Fatalf("Unmarshal: %v", err) + } + if back.N == nil { + t.Fatalf("Unmarshaled nil N field") + } + if *back.N != 42 { + t.Fatalf("*N = %d; want 42", *back.N) + } +}