gojay

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

commit 516d1730ff54dc802fc6749623cb77095628ecbf
parent 174d4d21ea2502f3d8c723c5b716dc46c5bfbc9e
Author: francoispqt <francois@parquet.ninja>
Date:   Mon, 29 Oct 2018 22:16:05 +0800

update godoc and readme, add examples

Diffstat:
Mdecode_array.go | 13+------------
Mdecode_example_test.go | 103++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mdecode_object.go | 16----------------
Mdecode_pool.go | 3++-
Mencode_example_test.go | 39+++++++++++++++++++++++++++++++++++++++
Mgojay.go | 3+++
Agojay_example_test.go | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 220 insertions(+), 30 deletions(-)

diff --git a/decode_array.go b/decode_array.go @@ -177,18 +177,7 @@ func (dec *Decoder) skipArray() (int, error) { // DecodeArrayFunc is a func type implementing UnmarshalerJSONArray. // Use it to cast a `func(*Decoder) error` to Unmarshal an array on the fly. -// -// strSlice := make([]string, 0) -// dec := gojay.NewDecoder(io.Reader) -// -// err := dec.DecodeArray( dec.DecodeArray(gojay.DecodeArrayFunc(func(dec *gojay.Decoder) error { -// var str string -// if err := dec.AddString(&str); err != nil { -// return err -// } -// strSlice = append(strSplice, str) -// return nil -// }))) + type DecodeArrayFunc func(*Decoder) error // UnmarshalJSONArray implements UnmarshalerJSONArray. diff --git a/decode_example_test.go b/decode_example_test.go @@ -36,7 +36,7 @@ func ExampleUnmarshal_invalidType() { fmt.Println(err) // "Cannot unmarshal JSON to type '*struct{}'" } -func ExampleDecode_string() { +func ExampleDecoder_Decode_string() { var str string dec := gojay.BorrowDecoder(strings.NewReader(`"gojay"`)) err := dec.Decode(&str) @@ -47,3 +47,104 @@ func ExampleDecode_string() { } fmt.Println(str) // "gojay" } + +func ExampleDecodeObjectFunc() { + reader := strings.NewReader(`{ + "name": "John Doe", + "email": "john.doe@email.com" + }`) + dec := gojay.NewDecoder(reader) + + user := struct { + name string + email string + }{} + dec.DecodeObject(gojay.DecodeObjectFunc(func(dec *gojay.Decoder, k string) error { + switch k { + case "name": + return dec.String(&user.name) + case "email": + return dec.String(&user.email) + } + return nil + })) + + fmt.Printf("User\nname: %s\nemail: %s", user.name, user.email) + + // Output: + // User + // name: John Doe + // email: john.doe@email.com +} + +func ExampleDecodeArrayFunc() { + reader := strings.NewReader(`[ + "foo", + "bar" + ]`) + dec := gojay.NewDecoder(reader) + + strSlice := make([]string, 0) + err := dec.DecodeArray(gojay.DecodeArrayFunc(func(dec *gojay.Decoder) error { + var str string + if err := dec.AddString(&str); err != nil { + return err + } + strSlice = append(strSlice, str) + return nil + })) + + if err != nil { + log.Fatal(err) + } + + fmt.Print(strSlice) + // Output: + // [foo bar] +} + +func ExampleNewDecoder() { + reader := strings.NewReader(`"gojay"`) + dec := gojay.NewDecoder(reader) + + var str string + err := dec.DecodeString(&str) + if err != nil { + log.Fatal(err) + } + + fmt.Println(str) + // Output: + // gojay +} + +func ExampleBorrowDecoder() { + reader := strings.NewReader(`"gojay"`) + dec := gojay.BorrowDecoder(reader) + defer dec.Release() + + var str string + err := dec.DecodeString(&str) + if err != nil { + log.Fatal(err) + } + + fmt.Println(str) + // Output: + // gojay +} + +func ExampleDecoder_DecodeBool() { + reader := strings.NewReader(`true`) + dec := gojay.NewDecoder(reader) + + var b bool + err := dec.DecodeBool(&b) + if err != nil { + log.Fatal(err) + } + + fmt.Println(b) + // Output: + // true +} diff --git a/decode_object.go b/decode_object.go @@ -343,22 +343,6 @@ func (dec *Decoder) skipData() error { // DecodeObjectFunc is a func type implementing UnmarshalerJSONObject. // Use it to cast a `func(*Decoder, k string) error` to Unmarshal an object on the fly. -// -// user := struct{ -// name string -// email string -// }{} -// dec := gojay.NewDecoder(io.Reader) -// -// dec.DecodeObject(gojay.DecodeObjectFunc(func(dec *gojay.Decoder, k string) error { -// switch k { -// case "name": -// return dec.String(&user.name) -// case "email": -// return dec.String(&user.email) -// } -// return nil -// })) type DecodeObjectFunc func(*Decoder, string) error // UnmarshalJSONObject implements UnmarshalerJSONObject. diff --git a/decode_pool.go b/decode_pool.go @@ -35,7 +35,8 @@ func newDecoderPool() interface{} { // BorrowDecoder borrows a Decoder from the pool. // It takes an io.Reader implementation as data input. -// It initiates the done channel returned by Done(). +// +// In order to benefit from the pool, a borrowed decoder must be released after usage. func BorrowDecoder(r io.Reader) *Decoder { return borrowDecoder(r, 512) } diff --git a/encode_example_test.go b/encode_example_test.go @@ -3,6 +3,7 @@ package gojay_test import ( "fmt" "log" + "os" "github.com/francoispqt/gojay" ) @@ -24,3 +25,41 @@ func ExampleMarshal_bool() { } fmt.Println(string(d)) // true } + +func ExampleNewEncoder() { + enc := gojay.BorrowEncoder(os.Stdout) + + var str = "gojay" + err := enc.EncodeString(str) + if err != nil { + log.Fatal(err) + } + // Output: + // "gojay" +} + +func ExampleBorrowEncoder() { + enc := gojay.BorrowEncoder(os.Stdout) + defer enc.Release() + + var str = "gojay" + err := enc.EncodeString(str) + if err != nil { + log.Fatal(err) + } + // Output: + // "gojay" +} + +func ExampleEncoder_EncodeString() { + enc := gojay.BorrowEncoder(os.Stdout) + defer enc.Release() + + var str = "gojay" + err := enc.EncodeString(str) + if err != nil { + log.Fatal(err) + } + // Output: + // "gojay" +} diff --git a/gojay.go b/gojay.go @@ -4,4 +4,7 @@ // // It aims at performance and usability by relying on simple interfaces // to decode and encode structures, slices, arrays and even channels. +// +// On top of the simple interfaces to implement, gojay provides lots of helpers to decode and encode +// multiple of different types natively such as bit.Int, sql.NullString or time.Time package gojay diff --git a/gojay_example_test.go b/gojay_example_test.go @@ -0,0 +1,73 @@ +package gojay_test + +import ( + "fmt" + "log" + "os" + "strings" + + "github.com/francoispqt/gojay" +) + +type User struct { + ID int + Name string + Email string +} + +func (u *User) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { + switch k { + case "id": + return dec.Int(&u.ID) + case "name": + return dec.String(&u.Name) + case "email": + return dec.String(&u.Email) + } + return nil +} + +func (u *User) NKeys() int { + return 3 +} + +func (u *User) MarshalJSONObject(enc *gojay.Encoder) { + enc.IntKey("id", u.ID) + enc.StringKey("name", u.Name) + enc.StringKey("email", u.Email) +} + +func (u *User) IsNil() bool { + return u == nil +} + +func Example_decodeEncode() { + reader := strings.NewReader(`{ + "id": 1, + "name": "John Doe", + "email": "john.doe@email.com" + }`) + dec := gojay.BorrowDecoder(reader) + defer dec.Release() + + u := &User{} + err := dec.Decode(u) + if err != nil { + log.Fatal(err) + } + + enc := gojay.BorrowEncoder(os.Stdout) + err = enc.Encode(u) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("\nUser ID: %d\nName: %s\nEmail: %s\n", + u.ID, u.Name, u.Email) + + // Output: + // {"id":1,"name":"John Doe","email":"john.doe@email.com"} + // User ID: 1 + // Name: John Doe + // Email: john.doe@email.com +}