gojay

high performance JSON encoder/decoder with stream API for Golang
git clone git://git.lair.cx/gojay
Log | Files | Refs | README | LICENSE

commit 53aa594e2a908ee689d67fd40ff3da0bc273442f
parent c8f4b96d86a7496240343e2edfa511f02be9ff74
Author: francoispqt <francois@parquet.ninja>
Date:   Sat, 19 May 2018 23:24:48 +0800

add uint64 to encoding, simplify encoding API

Diffstat:
MREADME.md | 82++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mencode_array.go | 36++++++++++++++++++++++++++++++------
Mencode_bool.go | 33+++++++++++++++++++++++++++------
Mencode_interface.go | 4++--
Mencode_number.go | 293-------------------------------------------------------------------------------
Aencode_number_float.go | 192+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aencode_number_int.go | 193+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mencode_number_test.go | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aencode_number_uint.go | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mencode_object.go | 38++++++++++++++++++++++++++++++++------
Mencode_string.go | 34++++++++++++++++++++++++++++------
11 files changed, 766 insertions(+), 360 deletions(-)

diff --git a/README.md b/README.md @@ -54,11 +54,11 @@ type user struct { func (u *user) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { switch key { case "id": - return dec.AddInt(&u.id) + return dec.Int(&u.id) case "name": - return dec.AddString(&u.name) + return dec.String(&u.name) case "email": - return dec.AddString(&u.email) + return dec.String(&u.email) } return nil } @@ -145,27 +145,27 @@ if err := dec.Decode(&str); err != nil { `*gojay.Decoder` has multiple methods to decode to specific types: * Decode ```go -func (dec *Decoder) Decode(v interface{}) error +func (dec *gojay.Decoder) Decode(v interface{}) error ``` * DecodeObject ```go -func (dec *Decoder) DecodeObject(v UnmarshalerJSONObject) error +func (dec *gojay.Decoder) DecodeObject(v UnmarshalerJSONObject) error ``` * DecodeArray ```go -func (dec *Decoder) DecodeArray(v UnmarshalerJSONArray) error +func (dec *gojay.Decoder) DecodeArray(v UnmarshalerJSONArray) error ``` * DecodeInt ```go -func (dec *Decoder) DecodeInt(v *int) error +func (dec *gojay.Decoder) DecodeInt(v *int) error ``` * DecodeBool ```go -func (dec *Decoder) DecodeBool(v *bool) error +func (dec *gojay.Decoder) DecodeBool(v *bool) error ``` * DecodeString ```go -func (dec *Decoder) DecodeString(v *string) error +func (dec *gojay.Decoder) DecodeString(v *string) error ``` @@ -175,7 +175,7 @@ func (dec *Decoder) DecodeString(v *string) error To unmarshal a JSON object to a structure, the structure must implement the UnmarshalerJSONObject interface: ```go type UnmarshalerJSONObject interface { - UnmarshalJSONObject(*Decoder, string) error + UnmarshalJSONObject(*gojay.Decoder, string) error NKeys() int } ``` @@ -194,11 +194,11 @@ type user struct { func (u *user) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { switch k { case "id": - return dec.AddInt(&u.id) + return dec.Int(&u.id) case "name": - return dec.AddString(&u.name) + return dec.String(&u.name) case "email": - return dec.AddString(&u.email) + return dec.String(&u.email) } return nil } @@ -215,7 +215,7 @@ type message map[string]string // Implementing Unmarshaler func (m message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { str := "" - err := dec.AddString(&str) + err := dec.String(&str) if err != nil { return err } @@ -234,7 +234,7 @@ func (m message) NKeys() int { To unmarshal a JSON object to a slice an array or a channel, it must implement the UnmarshalerJSONArray interface: ```go type UnmarshalerJSONArray interface { - UnmarshalJSONArray(*Decoder) error + UnmarshalJSONArray(*gojay.Decoder) error } ``` UnmarshalJSONArray method takes one argument, a pointer to the Decoder (*gojay.Decoder). If the JSON data is not an array, the Unmarshal method will never be called. @@ -245,7 +245,7 @@ type testSlice []string // implement UnmarshalerJSONArray func (t *testStringArr) UnmarshalJSONArray(dec *gojay.Decoder) error { str := "" - if err := dec.AddString(&str); err != nil { + if err := dec.String(&str); err != nil { return err } *t = append(*t, str) @@ -259,7 +259,7 @@ type ChannelString chan string // implement UnmarshalerJSONArray func (c ChannelArray) UnmarshalJSONArray(dec *gojay.Decoder) error { str := "" - if err := dec.AddString(&str); err != nil { + if err := dec.String(&str); err != nil { return err } c <- str @@ -300,9 +300,9 @@ type user struct { } // implement MarshalerJSONObject func (u *user) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddIntKey("id", u.id) - enc.AddStringKey("name", u.name) - enc.AddStringKey("email", u.email) + enc.IntKey("id", u.id) + enc.StringKey("name", u.name) + enc.StringKey("email", u.email) } func (u *user) IsNil() bool { return u == nil @@ -390,35 +390,35 @@ if err := enc.Encode(str); err != nil { `*gojay.Encoder` has multiple methods to encoder specific types to JSON: * Encode ```go -func (enc *Encoder) Encode(v interface{}) error +func (enc *gojay.Encoder) Encode(v interface{}) error ``` * EncodeObject ```go -func (enc *Encoder) EncodeObject(v MarshalerJSONObject) error +func (enc *gojay.Encoder) EncodeObject(v MarshalerJSONObject) error ``` * EncodeArray ```go -func (enc *Encoder) EncodeArray(v MarshalerJSONArray) error +func (enc *gojay.Encoder) EncodeArray(v MarshalerJSONArray) error ``` * EncodeInt ```go -func (enc *Encoder) EncodeInt(n int) error +func (enc *gojay.Encoder) EncodeInt(n int) error ``` * EncodeInt64 ```go -func (enc *Encoder) EncodeInt64(n int64) error +func (enc *gojay.Encoder) EncodeInt64(n int64) error ``` * EncodeFloat ```go -func (enc *Encoder) EncodeFloat(n float64) error +func (enc *gojay.Encoder) EncodeFloat(n float64) error ``` * EncodeBool ```go -func (enc *Encoder) EncodeBool(v bool) error +func (enc *gojay.Encoder) EncodeBool(v bool) error ``` * EncodeString ```go -func (enc *Encoder) EncodeString(s string) error +func (enc *gojay.Encoder) EncodeString(s string) error ``` ### Structs and Maps @@ -426,7 +426,7 @@ func (enc *Encoder) EncodeString(s string) error To encode a structure, the structure must implement the MarshalerJSONObject interface: ```go type MarshalerJSONObject interface { - MarshalJSONObject(enc *Encoder) + MarshalJSONObject(enc *gojay.Encoder) IsNil() bool } ``` @@ -443,9 +443,9 @@ type user struct { } // implement MarshalerJSONObject func (u *user) MarshalJSONObject(dec *gojay.Decoder, key string) { - dec.AddIntKey("id", u.id) - dec.AddStringKey("name", u.name) - dec.AddStringKey("email", u.email) + dec.IntKey("id", u.id) + dec.StringKey("name", u.name) + dec.StringKey("email", u.email) } func (u *user) IsNil() bool { return u == nil @@ -460,7 +460,7 @@ type message map[string]string // Implementing Marshaler func (m message) MarshalJSONObject(enc *gojay.Encoder) { for k, v := range m { - enc.AddStringKey(k, v) + enc.StringKey(k, v) } } @@ -473,7 +473,7 @@ func (m message) IsNil() bool { To encode an array or a slice, the slice/array must implement the MarshalerJSONArray interface: ```go type MarshalerJSONArray interface { - MarshalJSONArray(enc *Encoder) + MarshalJSONArray(enc *gojay.Encoder) IsNil() bool } ``` @@ -485,9 +485,9 @@ Example of implementation: ```go type users []*user // implement MarshalerJSONArray -func (u *users) MarshalJSONArray(dec *Decoder) { +func (u *users) MarshalJSONArray(dec *gojay.Decoder) { for _, e := range u { - enc.AddObject(e) + enc.Object(e) } } func (u *users) IsNil() bool { @@ -534,7 +534,7 @@ type ChannelStream chan *user func (c ChannelStream) UnmarshalStream(dec *gojay.StreamDecoder) error { u := &user{} - if err := dec.AddObject(u); err != nil { + if err := dec.Object(u); err != nil { return err } c <- u @@ -592,9 +592,9 @@ type user struct { } func (u *user) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddIntKey("id", u.id) - enc.AddStringKey("name", u.name) - enc.AddStringKey("email", u.email) + enc.IntKey("id", u.id) + enc.StringKey("name", u.name) + enc.StringKey("email", u.email) } func (u *user) IsNil() bool { return u == nil @@ -608,7 +608,7 @@ func (s StreamChan) MarshalStream(enc *gojay.StreamEncoder) { case <-enc.Done(): return case o := <-s: - enc.AddObject(o) + enc.Object(o) } } diff --git a/encode_array.go b/encode_array.go @@ -24,6 +24,30 @@ func (enc *Encoder) encodeArray(v MarshalerJSONArray) ([]byte, error) { // AddArray adds an implementation of MarshalerJSONArray to be encoded, must be used inside a slice or array encoding (does not encode a key) // value must implement Marshaler func (enc *Encoder) AddArray(v MarshalerJSONArray) { + enc.Array(v) +} + +// AddArrayOmitEmpty adds an array or slice to be encoded, must be used inside a slice or array encoding (does not encode a key) +// value must implement Marshaler +func (enc *Encoder) AddArrayOmitEmpty(v MarshalerJSONArray) { + enc.ArrayOmitEmpty(v) +} + +// AddArrayKey adds an array or slice to be encoded, must be used inside an object as it will encode a key +// value must implement Marshaler +func (enc *Encoder) AddArrayKey(key string, v MarshalerJSONArray) { + enc.ArrayKey(key, v) +} + +// AddArrayKeyOmitEmpty adds an array or slice to be encoded and skips it if it is nil. +// Must be called inside an object as it will encode a key. +func (enc *Encoder) AddArrayKeyOmitEmpty(key string, v MarshalerJSONArray) { + enc.ArrayKeyOmitEmpty(key, v) +} + +// Array adds an implementation of MarshalerJSONArray to be encoded, must be used inside a slice or array encoding (does not encode a key) +// value must implement Marshaler +func (enc *Encoder) Array(v MarshalerJSONArray) { if v.IsNil() { enc.grow(3) r := enc.getPreviousRune() @@ -44,9 +68,9 @@ func (enc *Encoder) AddArray(v MarshalerJSONArray) { enc.writeByte(']') } -// AddArrayOmitEmpty adds an array or slice to be encoded, must be used inside a slice or array encoding (does not encode a key) +// ArrayOmitEmpty adds an array or slice to be encoded, must be used inside a slice or array encoding (does not encode a key) // value must implement Marshaler -func (enc *Encoder) AddArrayOmitEmpty(v MarshalerJSONArray) { +func (enc *Encoder) ArrayOmitEmpty(v MarshalerJSONArray) { if v.IsNil() { return } @@ -60,9 +84,9 @@ func (enc *Encoder) AddArrayOmitEmpty(v MarshalerJSONArray) { enc.writeByte(']') } -// AddArrayKey adds an array or slice to be encoded, must be used inside an object as it will encode a key +// ArrayKey adds an array or slice to be encoded, must be used inside an object as it will encode a key // value must implement Marshaler -func (enc *Encoder) AddArrayKey(key string, v MarshalerJSONArray) { +func (enc *Encoder) ArrayKey(key string, v MarshalerJSONArray) { if v.IsNil() { enc.grow(2 + len(key)) r := enc.getPreviousRune() @@ -87,9 +111,9 @@ func (enc *Encoder) AddArrayKey(key string, v MarshalerJSONArray) { enc.writeByte(']') } -// AddArrayKeyOmitEmpty adds an array or slice to be encoded and skips it if it is nil. +// ArrayKeyOmitEmpty adds an array or slice to be encoded and skips it if it is nil. // Must be called inside an object as it will encode a key. -func (enc *Encoder) AddArrayKeyOmitEmpty(key string, v MarshalerJSONArray) { +func (enc *Encoder) ArrayKeyOmitEmpty(key string, v MarshalerJSONArray) { if v.IsNil() { return } diff --git a/encode_bool.go b/encode_bool.go @@ -29,6 +29,27 @@ func (enc *Encoder) encodeBool(v bool) ([]byte, error) { // AddBool adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key) func (enc *Encoder) AddBool(v bool) { + enc.Bool(v) +} + +// AddBoolOmitEmpty adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) AddBoolOmitEmpty(v bool) { + enc.BoolOmitEmpty(v) +} + +// AddBoolKey adds a bool to be encoded, must be used inside an object as it will encode a key. +func (enc *Encoder) AddBoolKey(key string, v bool) { + enc.BoolKey(key, v) +} + +// AddBoolKeyOmitEmpty adds a bool to be encoded and skips it if it is zero value. +// Must be used inside an object as it will encode a key. +func (enc *Encoder) AddBoolKeyOmitEmpty(key string, v bool) { + enc.BoolKeyOmitEmpty(key, v) +} + +// Bool adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) Bool(v bool) { enc.grow(5) r := enc.getPreviousRune() if r != '[' { @@ -41,8 +62,8 @@ func (enc *Encoder) AddBool(v bool) { } } -// AddBoolOmitEmpty adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddBoolOmitEmpty(v bool) { +// BoolOmitEmpty adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) BoolOmitEmpty(v bool) { if v == false { return } @@ -54,8 +75,8 @@ func (enc *Encoder) AddBoolOmitEmpty(v bool) { enc.writeString("true") } -// AddBoolKey adds a bool to be encoded, must be used inside an object as it will encode a key. -func (enc *Encoder) AddBoolKey(key string, value bool) { +// BoolKey adds a bool to be encoded, must be used inside an object as it will encode a key. +func (enc *Encoder) BoolKey(key string, value bool) { enc.grow(5 + len(key)) r := enc.getPreviousRune() if r != '{' { @@ -67,9 +88,9 @@ func (enc *Encoder) AddBoolKey(key string, value bool) { enc.buf = strconv.AppendBool(enc.buf, value) } -// AddBoolKeyOmitEmpty adds a bool to be encoded and skips it if it is zero value. +// BoolKeyOmitEmpty adds a bool to be encoded and skips it if it is zero value. // Must be used inside an object as it will encode a key. -func (enc *Encoder) AddBoolKeyOmitEmpty(key string, v bool) { +func (enc *Encoder) BoolKeyOmitEmpty(key string, v bool) { if v == false { return } diff --git a/encode_interface.go b/encode_interface.go @@ -31,7 +31,7 @@ func (enc *Encoder) Encode(v interface{}) error { case int8: return enc.EncodeInt(int(vt)) case uint64: - return enc.EncodeInt(int(vt)) + return enc.EncodeUint64(vt) case uint32: return enc.EncodeInt(int(vt)) case uint16: @@ -69,7 +69,7 @@ func (enc *Encoder) AddInterface(value interface{}) { case int8: enc.AddInt(int(vt)) case uint64: - enc.AddInt(int(vt)) + enc.AddUint64(vt) case uint32: enc.AddInt(int(vt)) case uint16: diff --git a/encode_number.go b/encode_number.go @@ -1,294 +1 @@ package gojay - -import "strconv" - -// EncodeInt encodes an int to JSON -func (enc *Encoder) EncodeInt(n int) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeInt(n) - _, err := enc.Write() - if err != nil { - return err - } - return nil -} - -// encodeInt encodes an int to JSON -func (enc *Encoder) encodeInt(n int) ([]byte, error) { - enc.buf = strconv.AppendInt(enc.buf, int64(n), 10) - return enc.buf, nil -} - -// EncodeInt64 encodes an int64 to JSON -func (enc *Encoder) EncodeInt64(n int64) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeInt64(n) - _, err := enc.Write() - if err != nil { - return err - } - return nil -} - -// encodeInt64 encodes an int to JSON -func (enc *Encoder) encodeInt64(n int64) ([]byte, error) { - enc.buf = strconv.AppendInt(enc.buf, n, 10) - return enc.buf, nil -} - -// EncodeFloat encodes a float64 to JSON -func (enc *Encoder) EncodeFloat(n float64) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeFloat(n) - _, err := enc.Write() - if err != nil { - return err - } - return nil -} - -// encodeFloat encodes a float64 to JSON -func (enc *Encoder) encodeFloat(n float64) ([]byte, error) { - enc.buf = strconv.AppendFloat(enc.buf, n, 'f', -1, 64) - return enc.buf, nil -} - -// EncodeFloat32 encodes a float32 to JSON -func (enc *Encoder) EncodeFloat32(n float32) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeFloat32(n) - _, err := enc.Write() - if err != nil { - return err - } - return nil -} - -func (enc *Encoder) encodeFloat32(n float32) ([]byte, error) { - enc.buf = strconv.AppendFloat(enc.buf, float64(n), 'f', -1, 32) - return enc.buf, nil -} - -// AddInt adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddInt(v int) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) -} - -// AddIntOmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddIntOmitEmpty(v int) { - if v == 0 { - return - } - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) -} - -// AddInt64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddInt64(v int64) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendInt(enc.buf, v, 10) -} - -// AddInt64OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddInt64OmitEmpty(v int64) { - if v == 0 { - return - } - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendInt(enc.buf, v, 10) -} - -// AddFloat adds a float64 to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddFloat(v float64) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64) -} - -// AddFloatOmitEmpty adds a float64 to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddFloatOmitEmpty(v float64) { - if v == 0 { - return - } - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64) -} - -// AddFloat32 adds a float32 to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddFloat32(v float32) { - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) -} - -// AddFloat32OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddFloat32OmitEmpty(v float32) { - if v == 0 { - return - } - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) -} - -// AddIntKey adds an int to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddIntKey(key string, v int) { - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) -} - -// AddIntKeyOmitEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddIntKeyOmitEmpty(key string, v int) { - if v == 0 { - return - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' && r != '[' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) -} - -// AddInt64Key adds an int64 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddInt64Key(key string, v int64) { - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendInt(enc.buf, v, 10) -} - -// AddInt64KeyOmitEmpty adds an int64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddInt64KeyOmitEmpty(key string, v int64) { - if v == 0 { - return - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendInt(enc.buf, v, 10) -} - -// AddFloatKey adds a float64 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddFloatKey(key string, value float64) { - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.grow(10) - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendFloat(enc.buf, value, 'f', -1, 64) -} - -// AddFloatKeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddFloatKeyOmitEmpty(key string, v float64) { - if v == 0 { - return - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64) -} - -// AddFloat32Key adds a float32 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddFloat32Key(key string, v float32) { - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeByte('"') - enc.writeByte(':') - enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) -} - -// AddFloat32KeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddFloat32KeyOmitEmpty(key string, v float32) { - if v == 0 { - return - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) -} diff --git a/encode_number_float.go b/encode_number_float.go @@ -0,0 +1,192 @@ +package gojay + +import "strconv" + +// EncodeFloat encodes a float64 to JSON +func (enc *Encoder) EncodeFloat(n float64) error { + if enc.isPooled == 1 { + panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) + } + _, _ = enc.encodeFloat(n) + _, err := enc.Write() + if err != nil { + return err + } + return nil +} + +// encodeFloat encodes a float64 to JSON +func (enc *Encoder) encodeFloat(n float64) ([]byte, error) { + enc.buf = strconv.AppendFloat(enc.buf, n, 'f', -1, 64) + return enc.buf, nil +} + +// EncodeFloat32 encodes a float32 to JSON +func (enc *Encoder) EncodeFloat32(n float32) error { + if enc.isPooled == 1 { + panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) + } + _, _ = enc.encodeFloat32(n) + _, err := enc.Write() + if err != nil { + return err + } + return nil +} + +func (enc *Encoder) encodeFloat32(n float32) ([]byte, error) { + enc.buf = strconv.AppendFloat(enc.buf, float64(n), 'f', -1, 32) + return enc.buf, nil +} + +// AddFloat adds a float64 to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) AddFloat(v float64) { + enc.Float(v) +} + +// AddFloatOmitEmpty adds a float64 to be encoded and skips it if its value is 0, +// must be used inside a slice or array encoding (does not encode a key). +func (enc *Encoder) AddFloatOmitEmpty(v float64) { + enc.FloatOmitEmpty(v) +} + +// Float adds a float64 to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) Float(v float64) { + enc.grow(10) + r := enc.getPreviousRune() + if r != '[' { + enc.writeByte(',') + } + enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64) +} + +// FloatOmitEmpty adds a float64 to be encoded and skips it if its value is 0, +// must be used inside a slice or array encoding (does not encode a key). +func (enc *Encoder) FloatOmitEmpty(v float64) { + if v == 0 { + return + } + enc.grow(10) + r := enc.getPreviousRune() + if r != '[' { + enc.writeByte(',') + } + enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64) +} + +// AddFloatKey adds a float64 to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) AddFloatKey(key string, v float64) { + enc.FloatKey(key, v) +} + +// AddFloatKeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. +// Must be used inside an object as it will encode a key +func (enc *Encoder) AddFloatKeyOmitEmpty(key string, v float64) { + enc.FloatKeyOmitEmpty(key, v) +} + +// FloatKey adds a float64 to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) FloatKey(key string, value float64) { + r := enc.getPreviousRune() + if r != '{' { + enc.writeByte(',') + } + enc.grow(10) + enc.writeByte('"') + enc.writeStringEscape(key) + enc.writeBytes(objKey) + enc.buf = strconv.AppendFloat(enc.buf, value, 'f', -1, 64) +} + +// FloatKeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. +// Must be used inside an object as it will encode a key +func (enc *Encoder) FloatKeyOmitEmpty(key string, v float64) { + if v == 0 { + return + } + enc.grow(10 + len(key)) + r := enc.getPreviousRune() + if r != '{' { + enc.writeByte(',') + } + enc.writeByte('"') + enc.writeStringEscape(key) + enc.writeBytes(objKey) + enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64) +} + +// AddFloat32 adds a float32 to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) AddFloat32(v float32) { + enc.Float32(v) +} + +// AddFloat32OmitEmpty adds an int to be encoded and skips it if its value is 0, +// must be used inside a slice or array encoding (does not encode a key). +func (enc *Encoder) AddFloat32OmitEmpty(v float32) { + enc.Float32OmitEmpty(v) +} + +// Float32 adds a float32 to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) Float32(v float32) { + r := enc.getPreviousRune() + if r != '[' { + enc.writeByte(',') + } + enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) +} + +// Float32OmitEmpty adds an int to be encoded and skips it if its value is 0, +// must be used inside a slice or array encoding (does not encode a key). +func (enc *Encoder) Float32OmitEmpty(v float32) { + if v == 0 { + return + } + enc.grow(10) + r := enc.getPreviousRune() + if r != '[' { + enc.writeByte(',') + } + enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) +} + +// AddFloat32Key adds a float32 to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) AddFloat32Key(key string, v float32) { + enc.Float32Key(key, v) +} + +// AddFloat32KeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. +// Must be used inside an object as it will encode a key +func (enc *Encoder) AddFloat32KeyOmitEmpty(key string, v float32) { + enc.Float32KeyOmitEmpty(key, v) +} + +// Float32Key adds a float32 to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) Float32Key(key string, v float32) { + enc.grow(10 + len(key)) + r := enc.getPreviousRune() + if r != '{' { + enc.writeByte(',') + } + enc.writeByte('"') + enc.writeStringEscape(key) + enc.writeByte('"') + enc.writeByte(':') + enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) +} + +// Float32KeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. +// Must be used inside an object as it will encode a key +func (enc *Encoder) Float32KeyOmitEmpty(key string, v float32) { + if v == 0 { + return + } + enc.grow(10 + len(key)) + r := enc.getPreviousRune() + if r != '{' { + enc.writeByte(',') + } + enc.writeByte('"') + enc.writeStringEscape(key) + enc.writeBytes(objKey) + enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) +} diff --git a/encode_number_int.go b/encode_number_int.go @@ -0,0 +1,193 @@ +package gojay + +import "strconv" + +// EncodeInt encodes an int to JSON +func (enc *Encoder) EncodeInt(n int) error { + if enc.isPooled == 1 { + panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) + } + _, _ = enc.encodeInt(n) + _, err := enc.Write() + if err != nil { + return err + } + return nil +} + +// encodeInt encodes an int to JSON +func (enc *Encoder) encodeInt(n int) ([]byte, error) { + enc.buf = strconv.AppendInt(enc.buf, int64(n), 10) + return enc.buf, nil +} + +// EncodeInt64 encodes an int64 to JSON +func (enc *Encoder) EncodeInt64(n int64) error { + if enc.isPooled == 1 { + panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) + } + _, _ = enc.encodeInt64(n) + _, err := enc.Write() + if err != nil { + return err + } + return nil +} + +// encodeInt64 encodes an int to JSON +func (enc *Encoder) encodeInt64(n int64) ([]byte, error) { + enc.buf = strconv.AppendInt(enc.buf, n, 10) + return enc.buf, nil +} + +// AddInt adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) AddInt(v int) { + enc.Int(v) +} + +// AddIntOmitEmpty adds an int to be encoded and skips it if its value is 0, +// must be used inside a slice or array encoding (does not encode a key). +func (enc *Encoder) AddIntOmitEmpty(v int) { + enc.IntOmitEmpty(v) +} + +// Int adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) Int(v int) { + enc.grow(10) + r := enc.getPreviousRune() + if r != '[' { + enc.writeByte(',') + } + enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) +} + +// IntOmitEmpty adds an int to be encoded and skips it if its value is 0, +// must be used inside a slice or array encoding (does not encode a key). +func (enc *Encoder) IntOmitEmpty(v int) { + if v == 0 { + return + } + enc.grow(10) + r := enc.getPreviousRune() + if r != '[' { + enc.writeByte(',') + } + enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) +} + +// AddIntKey adds an int to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) AddIntKey(key string, v int) { + enc.IntKey(key, v) +} + +// AddIntKeyOmitEmpty adds an int to be encoded and skips it if its value is 0. +// Must be used inside an object as it will encode a key. +func (enc *Encoder) AddIntKeyOmitEmpty(key string, v int) { + enc.IntKeyOmitEmpty(key, v) +} + +// IntKey adds an int to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) IntKey(key string, v int) { + enc.grow(10 + len(key)) + r := enc.getPreviousRune() + if r != '{' { + enc.writeByte(',') + } + enc.writeByte('"') + enc.writeStringEscape(key) + enc.writeBytes(objKey) + enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) +} + +// IntKeyOmitEmpty adds an int to be encoded and skips it if its value is 0. +// Must be used inside an object as it will encode a key. +func (enc *Encoder) IntKeyOmitEmpty(key string, v int) { + if v == 0 { + return + } + enc.grow(10 + len(key)) + r := enc.getPreviousRune() + if r != '{' && r != '[' { + enc.writeByte(',') + } + enc.writeByte('"') + enc.writeStringEscape(key) + enc.writeBytes(objKey) + enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) +} + +// AddInt64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) AddInt64(v int64) { + enc.Int64(v) +} + +// AddInt64OmitEmpty adds an int to be encoded and skips it if its value is 0, +// must be used inside a slice or array encoding (does not encode a key). +func (enc *Encoder) AddInt64OmitEmpty(v int64) { + enc.Int64OmitEmpty(v) +} + +// Int64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) Int64(v int64) { + enc.grow(10) + r := enc.getPreviousRune() + if r != '[' { + enc.writeByte(',') + } + enc.buf = strconv.AppendInt(enc.buf, v, 10) +} + +// Int64OmitEmpty adds an int to be encoded and skips it if its value is 0, +// must be used inside a slice or array encoding (does not encode a key). +func (enc *Encoder) Int64OmitEmpty(v int64) { + if v == 0 { + return + } + enc.grow(10) + r := enc.getPreviousRune() + if r != '[' { + enc.writeByte(',') + } + enc.buf = strconv.AppendInt(enc.buf, v, 10) +} + +// AddInt64Key adds an int64 to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) AddInt64Key(key string, v int64) { + enc.Int64Key(key, v) +} + +// AddInt64KeyOmitEmpty adds an int64 to be encoded and skips it if its value is 0. +// Must be used inside an object as it will encode a key. +func (enc *Encoder) AddInt64KeyOmitEmpty(key string, v int64) { + enc.Int64KeyOmitEmpty(key, v) +} + +// Int64Key adds an int64 to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) Int64Key(key string, v int64) { + enc.grow(10 + len(key)) + r := enc.getPreviousRune() + if r != '{' { + enc.writeByte(',') + } + enc.writeByte('"') + enc.writeStringEscape(key) + enc.writeBytes(objKey) + enc.buf = strconv.AppendInt(enc.buf, v, 10) +} + +// Int64KeyOmitEmpty adds an int64 to be encoded and skips it if its value is 0. +// Must be used inside an object as it will encode a key. +func (enc *Encoder) Int64KeyOmitEmpty(key string, v int64) { + if v == 0 { + return + } + enc.grow(10 + len(key)) + r := enc.getPreviousRune() + if r != '{' { + enc.writeByte(',') + } + enc.writeByte('"') + enc.writeStringEscape(key) + enc.writeBytes(objKey) + enc.buf = strconv.AppendInt(enc.buf, v, 10) +} diff --git a/encode_number_test.go b/encode_number_test.go @@ -95,6 +95,26 @@ func TestEncoderNumberEncodeAPIErrors(t *testing.T) { assert.Equal(t, "Test Error", err.Error(), "err should be of type InvalidUsagePooledEncoderError") }) + t.Run("encode-uint64-pool-error", func(t *testing.T) { + builder := &strings.Builder{} + enc := NewEncoder(builder) + enc.Release() + defer func() { + err := recover() + assert.NotNil(t, err, "err should not be nil") + assert.IsType(t, InvalidUsagePooledEncoderError(""), err, "err should be of type InvalidUsagePooledEncoderError") + }() + _ = enc.EncodeUint64(1) + assert.True(t, false, "should not be called as encoder should have panicked") + }) + t.Run("encode-unt64-write-error", func(t *testing.T) { + w := TestWriterError("") + enc := NewEncoder(w) + err := enc.EncodeUint64(1) + assert.NotNil(t, err, "err should not be nil") + assert.Equal(t, "Test Error", err.Error(), "err should be of type InvalidUsagePooledEncoderError") + + }) t.Run("encode-float64-pool-error", func(t *testing.T) { builder := &strings.Builder{} enc := NewEncoder(builder) @@ -322,3 +342,106 @@ func TestAddNumberFunc(t *testing.T) { assert.Equal(t, `[`, builder.String(), `builder.String() should be equal to {"test":10"`) }) } + +func TestEncoderUint64(t *testing.T) { + builder := &strings.Builder{} + enc := BorrowEncoder(builder) + err := enc.Encode(uint64(145509)) + assert.Nil(t, err, "err should be nil") + assert.Equal(t, "145509", builder.String(), "builder.String() should be 145509") +} + +func TestUint64Add(t *testing.T) { + t.Run("uint64-key", func(t *testing.T) { + builder := &strings.Builder{} + enc := BorrowEncoder(builder) + enc.writeByte('{') + enc.AddUint64Key("test", 10) + _, err := enc.Write() + assert.Nil(t, err, "err should be nil") + assert.Equal(t, `{"test":10`, builder.String(), `builder.String() should be equal to {"test":10"`) + }) + t.Run("uint64-key-2", func(t *testing.T) { + builder := &strings.Builder{} + enc := BorrowEncoder(builder) + enc.writeBytes([]byte(`{"test":1`)) + enc.AddUint64Key("test", 10) + _, err := enc.Write() + assert.Nil(t, err, "err should be nil") + assert.Equal(t, `{"test":1,"test":10`, builder.String(), `builder.String() should be equal to {"test":10"`) + }) + + t.Run("uint64-key-omit-empty", func(t *testing.T) { + builder := &strings.Builder{} + enc := BorrowEncoder(builder) + enc.writeByte('{') + enc.AddUint64KeyOmitEmpty("test", 10) + _, err := enc.Write() + assert.Nil(t, err, "err should be nil") + assert.Equal(t, `{"test":10`, builder.String(), `builder.String() should be equal to {"test":10"`) + }) + t.Run("uint64-key-omit-empty-2", func(t *testing.T) { + builder := &strings.Builder{} + enc := BorrowEncoder(builder) + enc.writeBytes([]byte(`{"test":1`)) + enc.AddUint64KeyOmitEmpty("test", 10) + _, err := enc.Write() + assert.Nil(t, err, "err should be nil") + assert.Equal(t, `{"test":1,"test":10`, builder.String(), `builder.String() should be equal to {"test":10"`) + }) + t.Run("uint64-key-omit-empty-3", func(t *testing.T) { + builder := &strings.Builder{} + enc := BorrowEncoder(builder) + enc.writeByte('{') + enc.AddUint64KeyOmitEmpty("test", 0) + _, err := enc.Write() + assert.Nil(t, err, "err should be nil") + assert.Equal(t, `{`, builder.String(), `builder.String() should be equal to {"test":10"`) + }) + t.Run("uint64", func(t *testing.T) { + builder := &strings.Builder{} + enc := BorrowEncoder(builder) + enc.writeByte('[') + enc.AddUint64(10) + _, err := enc.Write() + assert.Nil(t, err, "err should be nil") + assert.Equal(t, `[10`, builder.String(), `builder.String() should be equal to {"test":10"`) + }) + t.Run("uint64-2", func(t *testing.T) { + builder := &strings.Builder{} + enc := BorrowEncoder(builder) + enc.writeBytes([]byte(`[1`)) + enc.AddUint64(10) + _, err := enc.Write() + assert.Nil(t, err, "err should be nil") + assert.Equal(t, `[1,10`, builder.String(), `builder.String() should be equal to {"test":10"`) + }) + + t.Run("uint64-omit-empty", func(t *testing.T) { + builder := &strings.Builder{} + enc := BorrowEncoder(builder) + enc.writeByte('[') + enc.AddUint64OmitEmpty(10) + _, err := enc.Write() + assert.Nil(t, err, "err should be nil") + assert.Equal(t, `[10`, builder.String(), `builder.String() should be equal to {"test":10"`) + }) + t.Run("uint64-omit-empty-2", func(t *testing.T) { + builder := &strings.Builder{} + enc := BorrowEncoder(builder) + enc.writeBytes([]byte(`[1`)) + enc.AddUint64OmitEmpty(10) + _, err := enc.Write() + assert.Nil(t, err, "err should be nil") + assert.Equal(t, `[1,10`, builder.String(), `builder.String() should be equal to {"test":10"`) + }) + t.Run("uint64-omit-empty-3", func(t *testing.T) { + builder := &strings.Builder{} + enc := BorrowEncoder(builder) + enc.writeByte('[') + enc.AddUint64OmitEmpty(0) + _, err := enc.Write() + assert.Nil(t, err, "err should be nil") + assert.Equal(t, `[`, builder.String(), `builder.String() should be equal to {"test":10"`) + }) +} diff --git a/encode_number_uint.go b/encode_number_uint.go @@ -0,0 +1,98 @@ +package gojay + +import "strconv" + +// EncodeUint64 encodes an int64 to JSON +func (enc *Encoder) EncodeUint64(n uint64) error { + if enc.isPooled == 1 { + panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) + } + _, _ = enc.encodeUint64(n) + _, err := enc.Write() + if err != nil { + return err + } + return nil +} + +// encodeUint64 encodes an int to JSON +func (enc *Encoder) encodeUint64(n uint64) ([]byte, error) { + enc.buf = strconv.AppendUint(enc.buf, n, 10) + return enc.buf, nil +} + +// AddUint64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) AddUint64(v uint64) { + enc.Uint64(v) +} + +// AddUint64OmitEmpty adds an int to be encoded and skips it if its value is 0, +// must be used inside a slice or array encoding (does not encode a key). +func (enc *Encoder) AddUint64OmitEmpty(v uint64) { + enc.Uint64OmitEmpty(v) +} + +// Uint64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) Uint64(v uint64) { + enc.grow(10) + r := enc.getPreviousRune() + if r != '[' { + enc.writeByte(',') + } + enc.buf = strconv.AppendUint(enc.buf, v, 10) +} + +// Uint64OmitEmpty adds an int to be encoded and skips it if its value is 0, +// must be used inside a slice or array encoding (does not encode a key). +func (enc *Encoder) Uint64OmitEmpty(v uint64) { + if v == 0 { + return + } + enc.grow(10) + r := enc.getPreviousRune() + if r != '[' { + enc.writeByte(',') + } + enc.buf = strconv.AppendUint(enc.buf, v, 10) +} + +// AddUint64Key adds an int to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) AddUint64Key(key string, v uint64) { + enc.Uint64Key(key, v) +} + +// AddUint64KeyOmitEmpty adds an int to be encoded and skips it if its value is 0. +// Must be used inside an object as it will encode a key. +func (enc *Encoder) AddUint64KeyOmitEmpty(key string, v uint64) { + enc.Uint64KeyOmitEmpty(key, v) +} + +// Uint64Key adds an int to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) Uint64Key(key string, v uint64) { + enc.grow(10 + len(key)) + r := enc.getPreviousRune() + if r != '{' { + enc.writeByte(',') + } + enc.writeByte('"') + enc.writeStringEscape(key) + enc.writeBytes(objKey) + enc.buf = strconv.AppendUint(enc.buf, v, 10) +} + +// Uint64KeyOmitEmpty adds an int to be encoded and skips it if its value is 0. +// Must be used inside an object as it will encode a key. +func (enc *Encoder) Uint64KeyOmitEmpty(key string, v uint64) { + if v == 0 { + return + } + enc.grow(10 + len(key)) + r := enc.getPreviousRune() + if r != '{' && r != '[' { + enc.writeByte(',') + } + enc.writeByte('"') + enc.writeStringEscape(key) + enc.writeBytes(objKey) + enc.buf = strconv.AppendUint(enc.buf, v, 10) +} diff --git a/encode_object.go b/encode_object.go @@ -36,6 +36,32 @@ func (enc *Encoder) encodeObject(v MarshalerJSONObject) ([]byte, error) { // AddObject adds an object to be encoded, must be used inside a slice or array encoding (does not encode a key) // value must implement MarshalerJSONObject func (enc *Encoder) AddObject(v MarshalerJSONObject) { + enc.Object(v) +} + +// AddObjectOmitEmpty adds an object to be encoded or skips it if IsNil returns true. +// Must be used inside a slice or array encoding (does not encode a key) +// value must implement MarshalerJSONObject +func (enc *Encoder) AddObjectOmitEmpty(v MarshalerJSONObject) { + enc.ObjectOmitEmpty(v) +} + +// AddObjectKey adds a struct to be encoded, must be used inside an object as it will encode a key +// value must implement MarshalerJSONObject +func (enc *Encoder) AddObjectKey(key string, v MarshalerJSONObject) { + enc.ObjectKey(key, v) +} + +// AddObjectKeyOmitEmpty adds an object to be encoded or skips it if IsNil returns true. +// Must be used inside a slice or array encoding (does not encode a key) +// value must implement MarshalerJSONObject +func (enc *Encoder) AddObjectKeyOmitEmpty(key string, v MarshalerJSONObject) { + enc.ObjectKeyOmitEmpty(key, v) +} + +// Object adds an object to be encoded, must be used inside a slice or array encoding (does not encode a key) +// value must implement MarshalerJSONObject +func (enc *Encoder) Object(v MarshalerJSONObject) { if v.IsNil() { enc.grow(2) r := enc.getPreviousRune() @@ -56,10 +82,10 @@ func (enc *Encoder) AddObject(v MarshalerJSONObject) { enc.writeByte('}') } -// AddObjectOmitEmpty adds an object to be encoded or skips it if IsNil returns true. +// ObjectOmitEmpty adds an object to be encoded or skips it if IsNil returns true. // Must be used inside a slice or array encoding (does not encode a key) // value must implement MarshalerJSONObject -func (enc *Encoder) AddObjectOmitEmpty(v MarshalerJSONObject) { +func (enc *Encoder) ObjectOmitEmpty(v MarshalerJSONObject) { if v.IsNil() { return } @@ -73,9 +99,9 @@ func (enc *Encoder) AddObjectOmitEmpty(v MarshalerJSONObject) { enc.writeByte('}') } -// AddObjectKey adds a struct to be encoded, must be used inside an object as it will encode a key +// ObjectKey adds a struct to be encoded, must be used inside an object as it will encode a key // value must implement MarshalerJSONObject -func (enc *Encoder) AddObjectKey(key string, value MarshalerJSONObject) { +func (enc *Encoder) ObjectKey(key string, value MarshalerJSONObject) { if value.IsNil() { enc.grow(2 + len(key)) r := enc.getPreviousRune() @@ -100,10 +126,10 @@ func (enc *Encoder) AddObjectKey(key string, value MarshalerJSONObject) { enc.writeByte('}') } -// AddObjectKeyOmitEmpty adds an object to be encoded or skips it if IsNil returns true. +// ObjectKeyOmitEmpty adds an object to be encoded or skips it if IsNil returns true. // Must be used inside a slice or array encoding (does not encode a key) // value must implement MarshalerJSONObject -func (enc *Encoder) AddObjectKeyOmitEmpty(key string, value MarshalerJSONObject) { +func (enc *Encoder) ObjectKeyOmitEmpty(key string, value MarshalerJSONObject) { if value.IsNil() { return } diff --git a/encode_string.go b/encode_string.go @@ -32,6 +32,28 @@ func (enc *Encoder) AppendString(v string) { // AddString adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key) func (enc *Encoder) AddString(v string) { + enc.String(v) +} + +// AddStringOmitEmpty adds a string to be encoded or skips it if it is zero value. +// Must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) AddStringOmitEmpty(v string) { + enc.StringOmitEmpty(v) +} + +// AddStringKey adds a string to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) AddStringKey(key, v string) { + enc.StringKey(key, v) +} + +// AddStringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value. +// Must be used inside an object as it will encode a key +func (enc *Encoder) AddStringKeyOmitEmpty(key, v string) { + enc.StringKeyOmitEmpty(key, v) +} + +// String adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key) +func (enc *Encoder) String(v string) { enc.grow(len(v) + 4) r := enc.getPreviousRune() if r != '[' { @@ -43,9 +65,9 @@ func (enc *Encoder) AddString(v string) { enc.writeByte('"') } -// AddStringOmitEmpty adds a string to be encoded or skips it if it is zero value. +// StringOmitEmpty adds a string to be encoded or skips it if it is zero value. // Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddStringOmitEmpty(v string) { +func (enc *Encoder) StringOmitEmpty(v string) { if v == "" { return } @@ -59,8 +81,8 @@ func (enc *Encoder) AddStringOmitEmpty(v string) { enc.writeByte('"') } -// AddStringKey adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddStringKey(key, v string) { +// StringKey adds a string to be encoded, must be used inside an object as it will encode a key +func (enc *Encoder) StringKey(key, v string) { enc.grow(len(key) + len(v) + 5) r := enc.getPreviousRune() if r != '{' { @@ -74,9 +96,9 @@ func (enc *Encoder) AddStringKey(key, v string) { enc.writeByte('"') } -// AddStringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value. +// StringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value. // Must be used inside an object as it will encode a key -func (enc *Encoder) AddStringKeyOmitEmpty(key, v string) { +func (enc *Encoder) StringKeyOmitEmpty(key, v string) { if v == "" { return }