summaryrefslogtreecommitdiffstats
path: root/vendor
diff options
context:
space:
mode:
authorKarim Khaleel <code.karim@gmail.com>2023-11-05 11:14:10 +0300
committerStefan Haller <stefan@haller-berlin.de>2023-12-02 10:46:24 +0100
commitdf5b3693d6821d6d946afffb6002ea1dd4647929 (patch)
treef05bdd9f00852d9c42966e291cf726229028ff80 /vendor
parentb123719107312e2b451e6745db0031f1fd5005c5 (diff)
Add invopop/jsonschema fork
Diffstat (limited to 'vendor')
-rw-r--r--vendor/github.com/bahlo/generic-list-go/LICENSE27
-rw-r--r--vendor/github.com/bahlo/generic-list-go/README.md5
-rw-r--r--vendor/github.com/bahlo/generic-list-go/list.go235
-rw-r--r--vendor/github.com/buger/jsonparser/.gitignore12
-rw-r--r--vendor/github.com/buger/jsonparser/Dockerfile12
-rw-r--r--vendor/github.com/buger/jsonparser/LICENSE21
-rw-r--r--vendor/github.com/buger/jsonparser/Makefile36
-rw-r--r--vendor/github.com/buger/jsonparser/README.md365
-rw-r--r--vendor/github.com/buger/jsonparser/bytes.go47
-rw-r--r--vendor/github.com/buger/jsonparser/bytes_safe.go25
-rw-r--r--vendor/github.com/buger/jsonparser/bytes_unsafe.go44
-rw-r--r--vendor/github.com/buger/jsonparser/escape.go173
-rw-r--r--vendor/github.com/buger/jsonparser/fuzz.go117
-rw-r--r--vendor/github.com/buger/jsonparser/oss-fuzz-build.sh47
-rw-r--r--vendor/github.com/buger/jsonparser/parser.go1283
-rw-r--r--vendor/github.com/karimkhaleel/jsonschema/.gitignore2
-rw-r--r--vendor/github.com/karimkhaleel/jsonschema/.golangci.yml70
-rw-r--r--vendor/github.com/karimkhaleel/jsonschema/COPYING19
-rw-r--r--vendor/github.com/karimkhaleel/jsonschema/README.md368
-rw-r--r--vendor/github.com/karimkhaleel/jsonschema/comment_extractor.go93
-rw-r--r--vendor/github.com/karimkhaleel/jsonschema/id.go76
-rw-r--r--vendor/github.com/karimkhaleel/jsonschema/reflect.go1196
-rw-r--r--vendor/github.com/karimkhaleel/jsonschema/utils.go26
-rw-r--r--vendor/github.com/mailru/easyjson/LICENSE7
-rw-r--r--vendor/github.com/mailru/easyjson/buffer/pool.go278
-rw-r--r--vendor/github.com/mailru/easyjson/jwriter/writer.go405
-rw-r--r--vendor/github.com/wk8/go-ordered-map/v2/.gitignore1
-rw-r--r--vendor/github.com/wk8/go-ordered-map/v2/.golangci.yml80
-rw-r--r--vendor/github.com/wk8/go-ordered-map/v2/CHANGELOG.md38
-rw-r--r--vendor/github.com/wk8/go-ordered-map/v2/LICENSE201
-rw-r--r--vendor/github.com/wk8/go-ordered-map/v2/Makefile32
-rw-r--r--vendor/github.com/wk8/go-ordered-map/v2/README.md154
-rw-r--r--vendor/github.com/wk8/go-ordered-map/v2/json.go182
-rw-r--r--vendor/github.com/wk8/go-ordered-map/v2/orderedmap.go296
-rw-r--r--vendor/github.com/wk8/go-ordered-map/v2/yaml.go71
-rw-r--r--vendor/modules.txt20
36 files changed, 6063 insertions, 1 deletions
diff --git a/vendor/github.com/bahlo/generic-list-go/LICENSE b/vendor/github.com/bahlo/generic-list-go/LICENSE
new file mode 100644
index 000000000..6a66aea5e
--- /dev/null
+++ b/vendor/github.com/bahlo/generic-list-go/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/bahlo/generic-list-go/README.md b/vendor/github.com/bahlo/generic-list-go/README.md
new file mode 100644
index 000000000..68bbce9fb
--- /dev/null
+++ b/vendor/github.com/bahlo/generic-list-go/README.md
@@ -0,0 +1,5 @@
+# generic-list-go [![CI](https://github.com/bahlo/generic-list-go/actions/workflows/ci.yml/badge.svg)](https://github.com/bahlo/generic-list-go/actions/workflows/ci.yml)
+
+Go [container/list](https://pkg.go.dev/container/list) but with generics.
+
+The code is based on `container/list` in `go1.18beta2`.
diff --git a/vendor/github.com/bahlo/generic-list-go/list.go b/vendor/github.com/bahlo/generic-list-go/list.go
new file mode 100644
index 000000000..a06a7c612
--- /dev/null
+++ b/vendor/github.com/bahlo/generic-list-go/list.go
@@ -0,0 +1,235 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package list implements a doubly linked list.
+//
+// To iterate over a list (where l is a *List):
+// for e := l.Front(); e != nil; e = e.Next() {
+// // do something with e.Value
+// }
+//
+package list
+
+// Element is an element of a linked list.
+type Element[T any] struct {
+ // Next and previous pointers in the doubly-linked list of elements.
+ // To simplify the implementation, internally a list l is implemented
+ // as a ring, such that &l.root is both the next element of the last
+ // list element (l.Back()) and the previous element of the first list
+ // element (l.Front()).
+ next, prev *Element[T]
+
+ // The list to which this element belongs.
+ list *List[T]
+
+ // The value stored with this element.
+ Value T
+}
+
+// Next returns the next list element or nil.
+func (e *Element[T]) Next() *Element[T] {
+ if p := e.next; e.list != nil && p != &e.list.root {
+ return p
+ }
+ return nil
+}
+
+// Prev returns the previous list element or nil.
+func (e *Element[T]) Prev() *Element[T] {
+ if p := e.prev; e.list != nil && p != &e.list.root {
+ return p
+ }
+ return nil
+}
+
+// List represents a doubly linked list.
+// The zero value for List is an empty list ready to use.
+type List[T any] struct {
+ root Element[T] // sentinel list element, only &root, root.prev, and root.next are used
+ len int // current list length excluding (this) sentinel element
+}
+
+// Init initializes or clears list l.
+func (l *List[T]) Init() *List[T] {
+ l.root.next = &l.root
+ l.root.prev = &l.root
+ l.len = 0
+ return l
+}
+
+// New returns an initialized list.
+func New[T any]() *List[T] { return new(List[T]).Init() }
+
+// Len returns the number of elements of list l.
+// The complexity is O(1).
+func (l *List[T]) Len() int { return l.len }
+
+// Front returns the first element of list l or nil if the list is empty.
+func (l *List[T]) Front() *Element[T] {
+ if l.len == 0 {
+ return nil
+ }
+ return l.root.next
+}
+
+// Back returns the last element of list l or nil if the list is empty.
+func (l *List[T]) Back() *Element[T] {
+ if l.len == 0 {
+ return nil
+ }
+ return l.root.prev
+}
+
+// lazyInit lazily initializes a zero List value.
+func (l *List[T]) lazyInit() {
+ if l.root.next == nil {
+ l.Init()
+ }
+}
+
+// insert inserts e after at, increments l.len, and returns e.
+func (l *List[T]) insert(e, at *Element[T]) *Element[T] {
+ e.prev = at
+ e.next = at.next
+ e.prev.next = e
+ e.next.prev = e
+ e.list = l
+ l.len++
+ return e
+}
+
+// insertValue is a convenience wrapper for insert(&Element{Value: v}, at).
+func (l *List[T]) insertValue(v T, at *Element[T]) *Element[T] {
+ return l.insert(&Element[T]{Value: v}, at)
+}
+
+// remove removes e from its list, decrements l.len
+func (l *List[T]) remove(e *Element[T]) {
+ e.prev.next = e.next
+ e.next.prev = e.prev
+ e.next = nil // avoid memory leaks
+ e.prev = nil // avoid memory leaks
+ e.list = nil
+ l.len--
+}
+
+// move moves e to next to at.
+func (l *List[T]) move(e, at *Element[T]) {
+ if e == at {
+ return
+ }
+ e.prev.next = e.next
+ e.next.prev = e.prev
+
+ e.prev = at
+ e.next = at.next
+ e.prev.next = e
+ e.next.prev = e
+}
+
+// Remove removes e from l if e is an element of list l.
+// It returns the element value e.Value.
+// The element must not be nil.
+func (l *List[T]) Remove(e *Element[T]) T {
+ if e.list == l {
+ // if e.list == l, l must have been initialized when e was inserted
+ // in l or l == nil (e is a zero Element) and l.remove will crash
+ l.remove(e)
+ }
+ return e.Value
+}
+
+// PushFront inserts a new element e with value v at the front of list l and returns e.
+func (l *List[T]) PushFront(v T) *Element[T] {
+ l.lazyInit()
+ return l.insertValue(v, &l.root)
+}
+
+// PushBack inserts a new element e with value v at the back of list l and returns e.
+func (l *List[T]) PushBack(v T) *Element[T] {
+ l.lazyInit()
+ return l.insertValue(v, l.root.prev)
+}
+
+// InsertBefore inserts a new element e with value v immediately before mark and returns e.
+// If mark is not an element of l, the list is not modified.
+// The mark must not be nil.
+func (l *List[T]) InsertBefore(v T, mark *Element[T]) *Element[T] {
+ if mark.list != l {
+ return nil
+ }
+ // see comment in List.Remove about initialization of l
+ return l.insertValue(v, mark.prev)
+}
+
+// InsertAfter inserts a new element e with value v immediately after mark and returns e.
+// If mark is not an element of l, the list is not modified.
+// The mark must not be nil.
+func (l *List[T]) InsertAfter(v T, mark *Element[T]) *Element[T] {
+ if mark.list != l {
+ return nil
+ }
+ // see comment in List.Remove about initialization of l
+ return l.insertValue(v, mark)
+}
+
+// MoveToFront moves element e to the front of list l.
+// If e is not an element of l, the list is not modified.
+// The element must not be nil.
+func (l *List[T]) MoveToFront(e *Element[T]) {
+ if e.list != l || l.root.next == e {
+ return
+ }
+ // see comment in List.Remove about initialization of l
+ l.move(e, &l.root)
+}
+
+// MoveToBack moves element e to the back of list l.
+// If e is not an element of l, the list is not modified.
+// The element must not be nil.
+func (l *List[T]) MoveToBack(e *Element[T]) {
+ if e.list != l || l.root.prev == e {
+ return
+ }
+ // see comment in List.Remove about initialization of l
+ l.move(e, l.root.prev)
+}
+
+// MoveBefore moves element e to its new position before mark.
+// If e or mark is not an element of l, or e == mark, the list is not modified.
+// The element and mark must not be nil.
+func (l *List[T]) MoveBefore(e, mark *Element[T]) {
+ if e.list != l || e == mark || mark.list != l {
+ return
+ }
+ l.move(e, mark.prev)
+}
+
+// MoveAfter moves element e to its new position after mark.
+// If e or mark is not an element of l, or e == mark, the list is not modified.
+// The element and mark must not be nil.
+func (l *List[T]) MoveAfter(e, mark *Element[T]) {
+ if e.list != l || e == mark || mark.list != l {
+ return
+ }
+ l.move(e, mark)
+}
+
+// PushBackList inserts a copy of another list at the back of list l.
+// The lists l and other may be the same. They must not be nil.
+func (l *List[T]) PushBackList(other *List[T]) {
+ l.lazyInit()
+ for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() {
+ l.insertValue(e.Value, l.root.prev)
+ }
+}
+
+// PushFrontList inserts a copy of another list at the front of list l.
+// The lists l and other may be the same. They must not be nil.
+func (l *List[T]) PushFrontList(other *List[T]) {
+ l.lazyInit()
+ for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() {
+ l.insertValue(e.Value, &l.root)
+ }
+}
diff --git a/vendor/github.com/buger/jsonparser/.gitignore b/vendor/github.com/buger/jsonparser/.gitignore
new file mode 100644
index 000000000..5598d8a56
--- /dev/null
+++ b/vendor/github.com/buger/jsonparser/.gitignore
@@ -0,0 +1,12 @@
+
+*.test
+
+*.out
+
+*.mprof
+
+.idea
+
+vendor/github.com/buger/goterm/
+prof.cpu
+prof.mem
diff --git a/vendor/github.com/buger/jsonparser/Dockerfile b/vendor/github.com/buger/jsonparser/Dockerfile
new file mode 100644
index 000000000..37fc9fd0b
--- /dev/null
+++ b/vendor/github.com/buger/jsonparser/Dockerfile
@@ -0,0 +1,12 @@
+FROM golang:1.6
+
+RUN go get github.com/Jeffail/gabs
+RUN go get github.com/bitly/go-simplejson
+RUN go get github.com/pquerna/ffjson
+RUN go get github.com/antonholmquist/jason
+RUN go get github.com/mreiferson/go-ujson
+RUN go get -tags=unsafe -u github.com/ugorji/go/codec
+RUN go get github.com/mailru/easyjson
+
+WORKDIR /go/src/github.com/buger/jsonparser
+ADD . /go/src/github.com/buger/jsonparser \ No newline at end of file
diff --git a/vendor/github.com/buger/jsonparser/LICENSE b/vendor/github.com/buger/jsonparser/LICENSE
new file mode 100644
index 000000000..ac25aeb7d
--- /dev/null
+++ b/vendor/github.com/buger/jsonparser/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2016 Leonid Bugaev
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/buger/jsonparser/Makefile b/vendor/github.com/buger/jsonparser/Makefile
new file mode 100644
index 000000000..e843368cf
--- /dev/null
+++ b/vendor/github.com/buger/jsonparser/Makefile
@@ -0,0 +1,36 @@
+SOURCE = parser.go
+CONTAINER = jsonparser
+SOURCE_PATH = /go/src/github.com/buger/jsonparser
+BENCHMARK = JsonParser
+BENCHTIME = 5s
+TEST = .
+DRUN = docker run -v `pwd`:$(SOURCE_PATH) -i -t $(CONTAINER)
+
+build:
+ docker build -t $(CONTAINER) .
+
+race:
+ $(DRUN) --env GORACE="halt_on_error=1" go test ./. $(ARGS) -v -race -timeout 15s
+
+bench:
+ $(DRUN) go test $(LDFLAGS) -test.benchmem -bench $(BENCHMARK) ./benchmark/ $(ARGS) -benchtime $(BENCHTIME) -v
+
+bench_local:
+ $(DRUN) go test $(LDFLAGS) -test.benchmem -bench . $(ARGS) -benchtime $(BENCHTIME) -v
+
+profile:
+ $(DRUN) go test $(LDFLAGS) -test.benchmem -bench $(BENCHMARK) ./benchmark/ $(ARGS) -memprofile mem.mprof -v
+ $(DRUN) go test $(LDFLAGS) -test.benchmem -bench $(BENCHMARK) ./benchmark/ $(ARGS) -cpuprofile cpu.out -v
+ $(DRUN) go test $(LDFLAGS) -test.benchmem -bench $(BENCHMARK) ./benchmark/ $(ARGS) -c
+
+test:
+ $(DRUN) go test $(LDFLAGS) ./ -run $(TEST) -timeout 10s $(ARGS) -v
+
+fmt:
+ $(DRUN) go fmt ./...
+
+vet:
+ $(DRUN) go vet ./.
+
+bash:
+ $(DRUN) /bin/bash \ No newline at end of file
diff --git a/vendor/github.com/buger/jsonparser/README.md b/vendor/github.com/buger/jsonparser/README.md
new file mode 100644
index 000000000..d7e0ec397
--- /dev/null
+++ b/vendor/github.com/buger/jsonparser/README.md
@@ -0,0 +1,365 @@
+[![Go Report Card](https://goreportcard.com/badge/github.com/buger/jsonparser)](https://goreportcard.com/report/github.com/buger/jsonparser) ![License](https://img.shields.io/dub/l/vibe-d.svg)
+# Alternative JSON parser for Go (10x times faster standard library)
+
+It does not require you to know the structure of the payload (eg. create structs), and allows accessing fields by providing the path to them. It is up to **10 times faster** than standard `encoding/json` package (depending on payload size and usage), **allocates no memory**. See benchmarks below.
+
+## Rationale
+Originally I made this for a project that relies on a lot of 3rd party APIs that can be unpredictable and complex.
+I love simplicity and prefer to avoid external dependecies. `encoding/json` requires you to know exactly your data structures, or if you prefer to use `map[string]interface{}` instead, it will be very slow and hard to manage.
+I investigated what's on the market and found that most libraries are just wrappers around `encoding/json`, there is few options with own parsers (`ffjson`, `easyjson`), but they still requires you to create data structures.
+
+
+Goal of this project is to push JSON parser to the performance limits and not sacrifice with compliance and developer user experience.
+
+## Example
+For the given JSON our goal is to extract the user's full name, number of github followers and avatar.
+
+```go
+import "github.com/buger/jsonparser"
+
+...
+
+data := []byte(`{
+ "person": {
+ "name": {
+ "first": "Leonid",
+ "last": "Bugaev",
+ "fullName": "Leonid Bugaev"
+ },
+ "github": {
+ "handle": "buger",
+ "followers": 109
+ },
+ "avatars": [
+ { "url": "https://avatars1.githubusercontent.com/u/14009?v=3&s=460", "type": "thumbnail" }
+ ]
+ },
+ "company": {
+ "name": "Acme"
+ }
+}`)
+
+// You can specify key path by providing arguments to Get function
+jsonparser.Get(data, "person", "name", "fullName")
+
+// There is `GetInt` and `GetBoolean` helpers if you exactly know key data type
+jsonparser.GetInt(data, "person", "github", "followers")
+
+// When you try to get object, it will return you []byte slice pointer to data containing it
+// In `company` it will be `{"name": "Acme"}`
+jsonparser.Get(data, "company")
+
+// If the key doesn't exist it will throw an error
+var size int64
+if value, err := jsonparser.GetInt(data, "company", "size"); err == nil {
+ size = value
+}
+
+// You can use `ArrayEach` helper to iterate items [item1, item2 .... itemN]
+jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
+ fmt.Println(jsonparser.Get(value, "url"))
+}, "person", "avatars")
+
+// Or use can access fields by index!
+jsonparser.GetString(data, "person", "avatars", "[0]", "url")
+
+// You can use `ObjectEach` helper to iterate objects { "key1":object1, "key2":object2, .... "keyN":objectN }
+jsonparser.ObjectEach(data, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error {
+ fmt.Printf("Key: '%s'\n Value: '%s'\n Type: %s\n", string(key), string(value), dataType)
+ return nil
+}, "person", "name")
+
+// The most efficient way to extract multiple keys is `EachKey`
+
+paths := [][]string{
+ []string{"person", "name", "fullName"},
+ []string{"person", "avatars", "[0]", "url"},
+ []string{"company", "url"},
+}
+jsonparser.EachKey(data, func(idx int, value []byte, vt jsonparser.ValueType, err error){
+ switch idx {
+ case 0: // []string{"person", "name", "fullName"}
+ ...
+ case 1: // []string{"person", "avatars", "[0]", "url"}
+ ...
+ case 2: // []string{"company", "url"},
+ ...
+ }
+}, paths...)
+
+// For more information see docs below
+```
+
+## Need to speedup your app?
+
+I'm available for consulting and can help you push your app performance to the limits. Ping me at: leonsbox@gmail.com.
+
+## Reference
+
+Library API is really simple. You just need the `Get` method to perform any operation. The rest is just helpers around it.
+
+You also can view API at [godoc.org](https://godoc.org/github.com/buger/jsonparser)
+
+
+### **`Get`**
+```go
+func Get(data []byte, keys ...string) (value []byte, dataType jsonparser.ValueType, offset int, err error)
+```
+Receives data structure, and key path to extract value from.
+
+Returns:
+* `value` - Pointer to original data structure containing key value, or just empty slice if nothing found or error
+* `dataType` - Can be: `NotExist`, `String`, `Number`, `Object`, `Array`, `Boolean` or `Null`
+* `offset` - Offset from provided data structure where key value ends. Used mostly internally, for example for `ArrayEach` helper.
+* `err` - If the key is not found or any other parsing issue, it should return error. If key not found it also sets `dataType` to `NotExist`
+
+Accepts multiple keys to specify path to JSON value (in case of quering nested structures).
+If no keys are provided it will try to extract the closest JSON value (simple ones or object/array), useful for reading streams or arrays, see `ArrayEach` implementation.
+
+Note that keys can be an array indexes: `jsonparser.GetInt("person", "avatars", "[0]", "url")`, pretty cool, yeah?
+
+### **`GetString`**
+```go
+func GetString(data []byte, keys ...string) (val string, err error)
+```
+Returns strings properly handing escaped and unicode characters. Note that this will cause additional memory allocations.
+
+### **`GetUnsafeString`**
+If you need string in your app, and ready to sacrifice with support of escaped symbols in favor of speed. It returns string mapped to existing byte slice memory, without any allocations:
+```go
+s, _, := jsonparser.GetUnsafeString(data, "person", "name", "title")
+switch s {
+ case 'CEO':
+ ...
+ case 'Engineer'
+ ...
+ ...
+}
+```
+Note that `unsafe` here means that your string will exist until GC will free underlying byte slice, for most of cases it means that you can use this string only in current context, and should not pass it anywhere externally: through channels or any other way.
+
+
+### **`GetBoolean`**, **`GetInt`** and **`GetFloat`**
+```go
+func GetBoolean(data []byte, keys ...string) (val bool, err error)
+
+func GetFloat(data []byte, keys ...string) (val float64, err error)
+
+func GetInt(data []byte, keys ...string) (val int64, err error)
+```
+If you know the key type, you can use the helpers above.
+If key data type do not match, it will return error.
+
+### **`ArrayEach`**
+```go
+func ArrayEach(data []byte, cb func(value []byte, dataType jsonparser.ValueType, offset int, err error), keys ...string)
+```
+Needed for iterating arrays, accepts a callback function with the same return arguments as `Get`.
+
+### **`ObjectEach`**
+```go
+func ObjectEach(data []byte, callback func(key []byte, value []byte, dataType ValueType, offset int) error, keys ...string) (err error)
+```
+Needed for iterating object, accepts a callback function. Example:
+```go
+var handler func([]byte, []byte, jsonparser.ValueType, int) error
+handler = func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error {
+ //do stuff here
+}
+jsonparser.ObjectEach(myJson, handler)
+```
+
+
+### **`EachKey`**
+```go
+func EachKey(data []byte, cb func(idx int, value []byte, dataType jsonparser.ValueType, err error), paths ...[]string)
+```
+When you need to read multiple keys, and you do not afraid of low-level API `EachKey` is your friend. It read payload only single time, and calls callback function once path is found. For example when you call multiple times `Get`, it has to process payload multiple times, each time you call it. Depending on payload `EachKey` can be multiple times faster than `Get`. Path can use nested keys as well!
+
+```go
+paths := [][]string{
+ []string{"uuid"},
+ []string{"tz"},
+ []string{"ua"},
+ []string{"st"},
+}
+var data SmallPayload
+
+jsonparser.EachKey(smallFixture, func(idx int, value []byte, vt jsonparser.ValueType, err error){
+ switch idx {
+ case 0:
+ data.Uuid, _ = value
+ case 1:
+ v, _ := jsonparser.ParseInt(value)
+ data.Tz = int(v)
+ case 2:
+ data.Ua, _ = value
+ case 3:
+ v, _ := jsonparser.ParseInt(value)
+ data.St = int(v)
+ }
+}, paths...)
+```
+
+### **`Set`**
+```go
+func Set(data []byte, setValue []byte, keys ...string) (value []byte, err error)
+```
+Receives existing data structure, key path to set, and value to set at that key. *This functionality is experimental.*
+
+Returns:
+* `value` - Pointer to original data structure with updated or added key value.
+* `err` - If any parsing issue, it should return error.
+
+Accepts multiple keys to specify path to JSON value (in case of updating or creating nested structures).
+
+Note that keys can be an array indexes: `jsonparser.Set(data, []byte("http://github.com"), "person", "avatars", "[0]", "url")`
+
+### **`Delete`**
+```go
+func Delete(data []byte, keys ...string) value []byte
+```
+Receives existing data structure, and key path to delete. *This functionality is experimental.*
+
+Returns:
+* `value` - Pointer to original data structure with key path deleted if it can be found. If there is no key path, then the whole data structure is deleted.
+
+Accepts multiple keys to specify path to JSON value (in case of updating or creating nested structures).
+
+Note that keys can be an array indexes: `jsonparser.Delete(data, "person", "avatars", "[0]", "url")`
+
+
+## What makes it so fast?
+* It does not rely on `encoding/json`, `reflection` or `interface{}`, the only real package dependency is `bytes`.
+* Operates with JSON payload on byte level, providing you pointers to the original data structure: no memory allocation.
+* No automatic type conversions, by default everything is a []byte, but it provides you value type, so you can convert by yourself (there is few helpers included).
+* Does not parse full record, only keys you specified
+
+
+## Benchmarks
+
+There are 3 benchmark types, trying to simulate real-life usage for small, medium and large JSON payloads.
+For each metric, the lower value is better. Time/op is in nanoseconds. Values better than standard encoding/json marked as bold text.
+Benchmarks run on standard Linode 1024 box.
+
+Compared libraries:
+* https://golang.org/pkg/encoding/json
+* https://github.com/Jeffail/gabs
+* https://github.com/a8m/djson
+* https://github.com/bitly/go-simplejson
+* https://github.com/antonholmquist/jason
+* https://github.com/mreiferson/go-ujson
+* https://github.com/ugorji/go/codec
+* https://github.com/pquerna/ffjson
+* https://github.com/mailru/easyjson
+* https://github.com/buger/jsonparser
+
+#### TLDR
+If you want to skip next sections we have 2 winner: `jsonparser` and `easyjson`.
+`jsonparser` is up to 10 times faster than standard `encoding/json` package (depending on payload size and usage), and almost infinitely (literally) better in memory consumption because it operates with data on byte level, and provide direct slice pointers.
+`easyjson` wins in CPU in medium tests and frankly i'm impressed with this package: it is remarkable results considering that it is almost drop-in replacement for `encoding/json` (require some code generation).
+
+It's hard to fully compare `jsonparser` and `easyjson` (or `ffson`), they a true parsers and fully process record, unlike `jsonparser` which parse only keys you specified.
+
+If you searching for replacement of `encoding/json` while keeping structs, `easyjson` is an amazing choice. If you want to process dynamic JSON, have memory constrains, or more control over your data you should try `jsonparser`.
+
+`jsonparser` performance heavily depends on usage, and it works best when you do not need to process full record, only some keys. The more calls you need to make, the slower it wil