commit 3792b2abba1132dd3cf11fa14f48936e862e80d8
parent 251e643799caca0d89c83eb077bb5f299a282bce
Author: francoispqt <francois@parquet.ninja>
Date: Sat, 28 Apr 2018 21:22:17 +0800
rebase with master
Diffstat:
M | README.md | | | 92 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ |
1 file changed, 86 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
@@ -10,9 +10,10 @@
GoJay is a performant JSON encoder/decoder for Golang (currently the most performant, [see benchmarks](#benchmark-results)).
-It has a simple API and doesn't use reflection. It relies on small interfaces to decode/encode structures and slices.
+It has a simple API and doesn't use reflection. It relies on small interfaces to decode/encode structures and slices.
+
+Gojay also comes with powerful stream decoding features and an even faster [Unsafe](#unsafe-api) API.
-Gojay also comes with powerful stream decoding features.
# Get started
@@ -22,7 +23,12 @@ go get github.com/francoispqt/gojay
## Decoding
-Example of basic stucture decoding:
+Decoding is done through two different API similar to standard `encoding/json`:
+* [Unmarshal](#unmarshal-api)
+* [Decode](#decode-api)
+
+
+Example of basic stucture decoding with Unmarshal:
```go
import "github.com/francoispqt/gojay"
@@ -57,18 +63,79 @@ func main() {
}
```
-Or with the Decoder API (which takes an io.Reader):
+with Decode:
```go
func main() {
u := &user{}
- dec := gojay.NewDecoder(strings.NewReader(`{"id":1,"name":"gojay","email":"gojay@email.com"}`))
- err := dec.Decode(u)
+ dec := gojay.NewDecoder(bytes.NewReader([]byte(`{"id":1,"name":"gojay","email":"gojay@email.com"}`)))
+ err := dec.DecodeObject(d, u)
if err != nil {
log.Fatal(err)
}
}
```
+### Unmarshal API
+
+Unmarshal API decodes a `[]byte` to a given pointer with a single function.
+
+Behind the doors, Unmarshal API borrows a `*gojay.Decoder` resets its settings and decodes the data to the given pointer and releases the `*gojay.Decoder` to the pool when it finishes, whether it encounters an error or not.
+
+If it cannot find the right Decoding strategy for the type of the given pointer, it returns an `InvalidUnmarshalError`. You can test the error returned by doing `if ok := err.(InvalidUnmarshalError); ok {}`.
+
+Unmarshal API comes with three functions:
+* Unmarshal
+```go
+func Unmarshal(data []byte, v Interface{}) error
+```
+
+* UnmarshalObject
+```go
+func UnmarshalObject(data []byte, v UnmarshalerObject) error
+```
+
+* UnmarshalArray
+```go
+func UnmarshalArray(data []byte, v UnmarshalerArray) error
+```
+
+
+### Decode API
+
+Decode API decodes a `[]byte` to a given pointer by creating or borrowing a `*gojay.Decoder` with an `io.Reader` and calling `Decode` methods.
+
+*Getting a *gojay.Decoder or Borrowing*
+
+You can either get a fresh `*gojay.Decoder` calling `dec := gojay.NewDecoder(io.Reader)` or borrow one from the pool by calling `dec := gojay.BorrowDecoder(io.Reader)`.
+
+After using a decoder, you can release it by calling `dec.Release()`. Beware, if you reuse the decoder after releasing it, it will panic with an error of type `InvalidUsagePooledDecoderError`. If you want to fully benefit from the pooling, you must release your decoders after using.
+
+`*gojay.Decoder` has multiple methods to decode to specific types:
+* Decode
+```go
+func (dec *Decoder) DecodeInt(v *int) error
+```
+* DecodeObject
+```go
+func (dec *Decoder) DecodeObject(v UnmarshalerObject) error
+```
+* DecodeArray
+```go
+func (dec *Decoder) DecodeArray(v UnmarshalerArray) error
+```
+* DecodeInt
+```go
+func (dec *Decoder) DecodeInt(v *int) error
+```
+* DecodeBool
+```go
+func (dec *Decoder) DecodeBool(v *bool) error
+```
+* DecodeString
+```go
+func (dec *Decoder) DecodeString(v *string) error
+```
+
### Structs
#### UnmarshalerObject Interface
@@ -300,6 +367,19 @@ func main() {
}
```
+# Unsafe API
+
+Unsafe API has the same functions than the regular API, it only has `Unmarshal API` for now. It is unsafe because it makes assumptions on the quality of the given JSON.
+
+If you are not sure if you're JSON is valid, don't use the Unsafe API.
+
+Also, the `Unsafe` API does not copy the buffer when using Unmarshal API, which, in case of string decoding, can lead to data corruption if a byte buffer is reused. Using the `Decode` API makes `Unsafe` API safer as the io.Reader relies on `copy` builtin method and `Decoder` will have its own internal buffer :)
+
+Access the `Unsafe` API this way:
+```go
+gojay.Unsafe.Unmarshal(b, v)
+```
+
# Benchmarks