66package json
77
88import (
9+ "bytes"
910 jsonv2 "encoding/json/v2" //nolint:depguard // this package wraps it
1011 "io"
1112)
@@ -15,18 +16,38 @@ func isJSONv2Available() bool {
1516 return true
1617}
1718
18- // marshalV2 uses JSON v2 marshal with v1 compatibility options
19- func marshalV2 (v any ) ([]byte , error ) {
19+ // marshalV2Internal uses JSON v2 marshal with v1 compatibility options (no trailing newline)
20+ func marshalV2Internal (v any ) ([]byte , error ) {
2021 opts := jsonv2 .JoinOptions (
2122 jsonv2 .MatchCaseInsensitiveNames (true ),
2223 jsonv2 .FormatNilSliceAsNull (true ),
2324 jsonv2 .FormatNilMapAsNull (true ),
25+ jsonv2 .Deterministic (true ),
2426 )
2527 return jsonv2 .Marshal (v , opts )
2628}
2729
30+ // marshalV2 uses JSON v2 marshal with v1 compatibility options (with trailing newline for compatibility with standard library)
31+ func marshalV2 (v any ) ([]byte , error ) {
32+ result , err := marshalV2Internal (v )
33+ if err != nil {
34+ return nil , err
35+ }
36+
37+ return append (result , '\n' ), nil
38+ }
39+
2840// unmarshalV2 uses JSON v2 unmarshal with v1 compatibility options
2941func unmarshalV2 (data []byte , v any ) error {
42+ if len (data ) == 0 {
43+ return nil
44+ }
45+
46+ data = bytes .TrimSpace (data )
47+ if len (data ) == 0 {
48+ return nil
49+ }
50+
3051 opts := jsonv2 .JoinOptions (
3152 jsonv2 .MatchCaseInsensitiveNames (true ),
3253 )
@@ -40,7 +61,13 @@ type encoderV2 struct {
4061}
4162
4263func (e * encoderV2 ) Encode (v any ) error {
43- return jsonv2 .MarshalWrite (e .writer , v , e .opts )
64+ err := jsonv2 .MarshalWrite (e .writer , v , e .opts )
65+ if err != nil {
66+ return err
67+ }
68+
69+ _ , err = e .writer .Write ([]byte {'\n' })
70+ return err
4471}
4572
4673// newEncoderV2 creates a new JSON v2 streaming encoder
@@ -49,6 +76,7 @@ func newEncoderV2(writer io.Writer) Encoder {
4976 jsonv2 .MatchCaseInsensitiveNames (true ),
5077 jsonv2 .FormatNilSliceAsNull (true ),
5178 jsonv2 .FormatNilMapAsNull (true ),
79+ jsonv2 .Deterministic (true ),
5280 )
5381 return & encoderV2 {writer : writer , opts : opts }
5482}
@@ -60,7 +88,12 @@ type decoderV2 struct {
6088}
6189
6290func (d * decoderV2 ) Decode (v any ) error {
63- return jsonv2 .UnmarshalRead (d .reader , v , d .opts )
91+ err := jsonv2 .UnmarshalRead (d .reader , v , d .opts )
92+ // Handle EOF more gracefully to match standard library behavior
93+ if err != nil && err .Error () == "unexpected EOF" {
94+ return io .EOF
95+ }
96+ return err
6497}
6598
6699// newDecoderV2 creates a new JSON v2 streaming decoder
0 commit comments