jsontext: add support for encoding null (#5371)

This commit is contained in:
Marten Seemann
2025-10-11 13:08:06 +08:00
committed by GitHub
parent ca05442ab9
commit ae909aeb72
2 changed files with 33 additions and 1 deletions

View File

@@ -19,6 +19,7 @@ const (
kindUint
kindFloat
kindBool
kindNull
kindObjectStart
kindObjectEnd
kindArrayStart
@@ -60,6 +61,9 @@ func Bool(b bool) Token {
return Token{kind: kindBool, b: b}
}
// Null is a null token.
var Null Token = Token{kind: kindNull}
// BeginObject is the begin object token.
var BeginObject Token = Token{kind: kindObjectStart}
@@ -86,6 +90,7 @@ var (
colonByte = []byte(":")
trueByte = []byte("true")
falseByte = []byte("false")
nullByte = []byte("null")
openObjectByte = []byte("{")
closeObjectByte = []byte("}")
openArrayByte = []byte("[")
@@ -256,6 +261,11 @@ func (e *Encoder) WriteToken(t Token) error {
}
}
e.afterValue()
case kindNull:
if _, err = e.w.Write(nullByte); err != nil {
return err
}
e.afterValue()
case kindObjectStart:
if _, err = e.w.Write(openObjectByte); err != nil {
return err

View File

@@ -88,6 +88,8 @@ func TestEncoderNumbersAndBool(t *testing.T) {
enc.WriteToken(jsontext.True)
enc.WriteToken(jsontext.String("false"))
enc.WriteToken(jsontext.False)
enc.WriteToken(jsontext.String("nullv"))
enc.WriteToken(jsontext.Null)
enc.WriteToken(jsontext.EndObject)
output := buf.String()
@@ -99,6 +101,7 @@ func TestEncoderNumbersAndBool(t *testing.T) {
"float": 3.14,
"true": true,
"false": false,
"nullv": nil,
}, got)
}
@@ -126,6 +129,21 @@ func TestEncoderEmptyArray(t *testing.T) {
require.Equal(t, []any{}, got)
}
func TestEncoderArrayWithNulls(t *testing.T) {
buf := bytes.NewBuffer(nil)
enc := jsontext.NewEncoder(buf)
enc.WriteToken(jsontext.BeginArray)
enc.WriteToken(jsontext.Null)
enc.WriteToken(jsontext.String("x"))
enc.WriteToken(jsontext.Null)
enc.WriteToken(jsontext.EndArray)
output := buf.String()
var got []any
require.NoError(t, json.Unmarshal([]byte(output), &got))
require.Equal(t, []any{nil, "x", nil}, got)
}
func TestEncoderEscapedStrings(t *testing.T) {
t.Run("no escapes", func(t *testing.T) {
testEncoderEscapedStrings(t, "simplekey", "simplevalue")
@@ -210,6 +228,9 @@ func encodeValue(t testing.TB, enc *jsontext.Encoder, v any) (isSupported bool)
case bool:
require.NoError(t, enc.WriteToken(jsontext.Bool(val)))
return true
case nil:
require.NoError(t, enc.WriteToken(jsontext.Null))
return true
default:
return false
}
@@ -326,12 +347,13 @@ func FuzzEncoder(f *testing.F) {
examples := []string{
`{"hello": "world"}`,
`{"foo": 123, "bar": [1, 2, 3]}`,
`{"nested": {"a": 1, "b": [true, false, "foobar"]}}`,
`{"nested": {"a": 1, "b": [true, false, "foobar", null]}}`,
`[{"x": 1}, {"y": "foo"}]`,
`["foo", "bar"]`,
`["a", {"b": [1, 2, {"c": "d"}]}, 3]`,
`{"emptyObj": {}, "emptyArr": []}`,
`{"mixed": [1, "two", {"three": 3}]}`,
`[null]`,
}
for _, tc := range examples {
// first test that