Update vendor with go dep

This fix updates vendor with `go dep`

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Yong Tang 2017-04-28 09:14:54 -07:00
parent e08fb277fa
commit 6e3be7f3d5
8538 changed files with 2537051 additions and 81115 deletions

4
vendor/github.com/mailru/easyjson/.gitignore generated vendored Normal file
View file

@ -0,0 +1,4 @@
.root
*_easyjson.go
*.iml
.idea

8
vendor/github.com/mailru/easyjson/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,8 @@
language: go
go:
- tip
install:
- go get github.com/ugorji/go/codec
- go get github.com/pquerna/ffjson/fflib/v1
- go get github.com/golang/lint/golint

7
vendor/github.com/mailru/easyjson/LICENSE generated vendored Normal file
View file

@ -0,0 +1,7 @@
Copyright (c) 2016 Mail.Ru Group
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.

54
vendor/github.com/mailru/easyjson/Makefile generated vendored Normal file
View file

@ -0,0 +1,54 @@
PKG=github.com/mailru/easyjson
GOPATH:=$(PWD)/.root:$(GOPATH)
export GOPATH
all: test
.root/src/$(PKG):
mkdir -p $@
for i in $$PWD/* ; do ln -s $$i $@/`basename $$i` ; done
root: .root/src/$(PKG)
clean:
rm -rf .root
build:
go build -i -o .root/bin/easyjson $(PKG)/easyjson
generate: root build
.root/bin/easyjson -stubs \
.root/src/$(PKG)/tests/snake.go \
.root/src/$(PKG)/tests/data.go \
.root/src/$(PKG)/tests/omitempty.go \
.root/src/$(PKG)/tests/nothing.go \
.root/src/$(PKG)/tests/named_type.go
.root/bin/easyjson -all .root/src/$(PKG)/tests/data.go
.root/bin/easyjson -all .root/src/$(PKG)/tests/nothing.go
.root/bin/easyjson -all .root/src/$(PKG)/tests/errors.go
.root/bin/easyjson -snake_case .root/src/$(PKG)/tests/snake.go
.root/bin/easyjson -omit_empty .root/src/$(PKG)/tests/omitempty.go
.root/bin/easyjson -build_tags=use_easyjson .root/src/$(PKG)/benchmark/data.go
.root/bin/easyjson .root/src/$(PKG)/tests/nested_easy.go
.root/bin/easyjson .root/src/$(PKG)/tests/named_type.go
test: generate root
go test \
$(PKG)/tests \
$(PKG)/jlexer \
$(PKG)/gen \
$(PKG)/buffer
go test -benchmem -tags use_easyjson -bench . $(PKG)/benchmark
golint -set_exit_status .root/src/$(PKG)/tests/*_easyjson.go
bench-other: generate root
@go test -benchmem -bench . $(PKG)/benchmark
@go test -benchmem -tags use_ffjson -bench . $(PKG)/benchmark
@go test -benchmem -tags use_codec -bench . $(PKG)/benchmark
bench-python:
benchmark/ujson.sh
.PHONY: root clean generate test build

329
vendor/github.com/mailru/easyjson/README.md generated vendored Normal file
View file

@ -0,0 +1,329 @@
# easyjson [![Build Status](https://travis-ci.org/mailru/easyjson.svg?branch=master)](https://travis-ci.org/mailru/easyjson) [![Go Report Card](https://goreportcard.com/badge/github.com/mailru/easyjson)](https://goreportcard.com/report/github.com/mailru/easyjson)
Package easyjson provides a fast and easy way to marshal/unmarshal Go structs
to/from JSON without the use of reflection. In performance tests, easyjson
outperforms the standard `encoding/json` package by a factor of 4-5x, and other
JSON encoding packages by a factor of 2-3x.
easyjson aims to keep generated Go code simple enough so that it can be easily
optimized or fixed. Another goal is to provide users with the ability to
customize the generated code by providing options not available with the
standard `encoding/json` package, such as generating "snake_case" names or
enabling `omitempty` behavior by default.
## Usage
```sh
# install
go get -u github.com/mailru/easyjson/...
# run
easyjson -all <file>.go
```
The above will generate `<file>_easyjson.go` containing the appropriate marshaler and
unmarshaler funcs for all structs contained in `<file>.go`.
Please note that easyjson requires a full Go build environment and the `GOPATH`
environment variable to be set. This is because easyjson code generation
invokes `go run` on a temporary file (an approach to code generation borrowed
from [ffjson](https://github.com/pquerna/ffjson)).
## Options
```txt
Usage of easyjson:
-all
generate marshaler/unmarshalers for all structs in a file
-build_tags string
build tags to add to generated file
-leave_temps
do not delete temporary files
-no_std_marshalers
don't generate MarshalJSON/UnmarshalJSON funcs
-noformat
do not run 'gofmt -w' on output file
-omit_empty
omit empty fields by default
-output_filename string
specify the filename of the output
-pkg
process the whole package instead of just the given file
-snake_case
use snake_case names instead of CamelCase by default
-stubs
only generate stubs for marshaler/unmarshaler funcs
```
Using `-all` will generate marshalers/unmarshalers for all Go structs in the
file. If `-all` is not provided, then only those structs whose preceeding
comment starts with `easyjson:json` will have marshalers/unmarshalers
generated. For example:
```go
//easyjson:json
struct A{}
```
Additional option notes:
* `-snake_case` tells easyjson to generate snake\_case field names by default
(unless overridden by a field tag). The CamelCase to snake\_case conversion
algorithm should work in most cases (ie, HTTPVersion will be converted to
"http_version").
* `-build_tags` will add the specified build tags to generated Go sources.
## Generated Marshaler/Unmarshaler Funcs
For Go struct types, easyjson generates the funcs `MarshalEasyJSON` /
`UnmarshalEasyJSON` for marshaling/unmarshaling JSON. In turn, these satisify
the `easyjson.Marshaler` and `easyjson.Unmarshaler` interfaces and when used in
conjunction with `easyjson.Marshal` / `easyjson.Unmarshal` avoid unnecessary
reflection / type assertions during marshaling/unmarshaling to/from JSON for Go
structs.
easyjson also generates `MarshalJSON` and `UnmarshalJSON` funcs for Go struct
types compatible with the standard `json.Marshaler` and `json.Unmarshaler`
interfaces. Please be aware that using the standard `json.Marshal` /
`json.Unmarshal` for marshaling/unmarshaling will incur a significant
performance penalty when compared to using `easyjson.Marshal` /
`easyjson.Unmarshal`.
Additionally, easyjson exposes utility funcs that use the `MarshalEasyJSON` and
`UnmarshalEasyJSON` for marshaling/unmarshaling to and from standard readers
and writers. For example, easyjson provides `easyjson.MarshalToHTTPResponseWriter`
which marshals to the standard `http.ResponseWriter`. Please see the [GoDoc
listing](https://godoc.org/github.com/mailru/easyjson) for the full listing of
utility funcs that are available.
## Controlling easyjson Marshaling and Unmarshaling Behavior
Go types can provide their own `MarshalEasyJSON` and `UnmarshalEasyJSON` funcs
that satisify the `easyjson.Marshaler` / `easyjson.Unmarshaler` interfaces.
These will be used by `easyjson.Marshal` and `easyjson.Unmarshal` when defined
for a Go type.
Go types can also satisify the `easyjson.Optional` interface, which allows the
type to define its own `omitempty` logic.
## Type Wrappers
easyjson provides additional type wrappers defined in the `easyjson/opt`
package. These wrap the standard Go primitives and in turn satisify the
easyjson interfaces.
The `easyjson/opt` type wrappers are useful when needing to distinguish between
a missing value and/or when needing to specifying a default value. Type
wrappers allow easyjson to avoid additional pointers and heap allocations and
can significantly increase performance when used properly.
## Memory Pooling
easyjson uses a buffer pool that allocates data in increasing chunks from 128
to 32768 bytes. Chunks of 512 bytes and larger will be reused with the help of
`sync.Pool`. The maximum size of a chunk is bounded to reduce redundant memory
allocation and to allow larger reusable buffers.
easyjson's custom allocation buffer pool is defined in the `easyjson/buffer`
package, and the default behavior pool behavior can be modified (if necessary)
through a call to `buffer.Init()` prior to any marshaling or unmarshaling.
Please see the [GoDoc listing](https://godoc.org/github.com/mailru/easyjson/buffer)
for more information.
## Issues, Notes, and Limitations
* easyjson is still early in its development. As such, there are likely to be
bugs and missing features when compared to `encoding/json`. In the case of a
missing feature or bug, please create a GitHub issue. Pull requests are
welcome!
* Unlike `encoding/json`, object keys are case-sensitive. Case-insensitive
matching is not currently provided due to the significant performance hit
when doing case-insensitive key matching. In the future, case-insensitive
object key matching may be provided via an option to the generator.
* easyjson makes use of `unsafe`, which simplifies the code and
provides significant performance benefits by allowing no-copy
conversion from `[]byte` to `string`. That said, `unsafe` is used
only when unmarshaling and parsing JSON, and any `unsafe` operations
/ memory allocations done will be safely deallocated by
easyjson. Set the build tag `easyjson_nounsafe` to compile it
without `unsafe`.
* easyjson is compatible with Google App Engine. The `appengine` build
tag (set by App Engine's environment) will automatically disable the
use of `unsafe`, which is not allowed in App Engine's Standard
Environment. Note that the use with App Engine is still experimental.
* Floats are formatted using the default precision from Go's `strconv` package.
As such, easyjson will not correctly handle high precision floats when
marshaling/unmarshaling JSON. Note, however, that there are very few/limited
uses where this behavior is not sufficient for general use. That said, a
different package may be needed if precise marshaling/unmarshaling of high
precision floats to/from JSON is required.
* While unmarshaling, the JSON parser does the minimal amount of work needed to
skip over unmatching parens, and as such full validation is not done for the
entire JSON value being unmarshaled/parsed.
* Currently there is no true streaming support for encoding/decoding as
typically for many uses/protocols the final, marshaled length of the JSON
needs to be known prior to sending the data. Currently this is not possible
with easyjson's architecture.
## Benchmarks
Most benchmarks were done using the example
[13kB example JSON](https://dev.twitter.com/rest/reference/get/search/tweets)
(9k after eliminating whitespace). This example is similar to real-world data,
is well-structured, and contains a healthy variety of different types, making
it ideal for JSON serialization benchmarks.
Note:
* For small request benchmarks, an 80 byte portion of the above example was
used.
* For large request marshaling benchmarks, a struct containing 50 regular
samples was used, making a ~500kB output JSON.
* Benchmarks are showing the results of easyjson's default behaviour,
which makes use of `unsafe`.
Benchmarks are available in the repository and can be run by invoking `make`.
### easyjson vs. encoding/json
easyjson is roughly 5-6 times faster than the standard `encoding/json` for
unmarshaling, and 3-4 times faster for non-concurrent marshaling. Concurrent
marshaling is 6-7x faster if marshaling to a writer.
### easyjson vs. ffjson
easyjson uses the same approach for JSON marshaling as
[ffjson](https://github.com/pquerna/ffjson), but takes a significantly
different approach to lexing and parsing JSON during unmarshaling. This means
easyjson is roughly 2-3x faster for unmarshaling and 1.5-2x faster for
non-concurrent unmarshaling.
As of this writing, `ffjson` seems to have issues when used concurrently:
specifically, large request pooling hurts `ffjson`'s performance and causes
scalability issues. These issues with `ffjson` can likely be fixed, but as of
writing remain outstanding/known issues with `ffjson`.
easyjson and `ffjson` have similar performance for small requests, however
easyjson outperforms `ffjson` by roughly 2-5x times for large requests when
used with a writer.
### easyjson vs. go/codec
[go/codec](https://github.com/ugorji/go) provides
compile-time helpers for JSON generation. In this case, helpers do not work
like marshalers as they are encoding-independent.
easyjson is generally 2x faster than `go/codec` for non-concurrent benchmarks
and about 3x faster for concurrent encoding (without marshaling to a writer).
In an attempt to measure marshaling performance of `go/codec` (as opposed to
allocations/memcpy/writer interface invocations), a benchmark was done with
resetting length of a byte slice rather than resetting the whole slice to nil.
However, the optimization in this exact form may not be applicable in practice,
since the memory is not freed between marshaling operations.
### easyjson vs 'ujson' python module
[ujson](https://github.com/esnme/ultrajson) is using C code for parsing, so it
is interesting to see how plain golang compares to that. It is imporant to note
that the resulting object for python is slower to access, since the library
parses JSON object into dictionaries.
easyjson is slightly faster for unmarshaling and 2-3x faster than `ujson` for
marshaling.
### Benchmark Results
`ffjson` results are from February 4th, 2016, using the latest `ffjson` and go1.6.
`go/codec` results are from March 4th, 2016, using the latest `go/codec` and go1.6.
#### Unmarshaling
| lib | json size | MB/s | allocs/op | B/op |
|:---------|:----------|-----:|----------:|------:|
| standard | regular | 22 | 218 | 10229 |
| standard | small | 9.7 | 14 | 720 |
| | | | | |
| easyjson | regular | 125 | 128 | 9794 |
| easyjson | small | 67 | 3 | 128 |
| | | | | |
| ffjson | regular | 66 | 141 | 9985 |
| ffjson | small | 17.6 | 10 | 488 |
| | | | | |
| codec | regular | 55 | 434 | 19299 |
| codec | small | 29 | 7 | 336 |
| | | | | |
| ujson | regular | 103 | N/A | N/A |
#### Marshaling, one goroutine.
| lib | json size | MB/s | allocs/op | B/op |
|:----------|:----------|-----:|----------:|------:|
| standard | regular | 75 | 9 | 23256 |
| standard | small | 32 | 3 | 328 |
| standard | large | 80 | 17 | 1.2M |
| | | | | |
| easyjson | regular | 213 | 9 | 10260 |
| easyjson* | regular | 263 | 8 | 742 |
| easyjson | small | 125 | 1 | 128 |
| easyjson | large | 212 | 33 | 490k |
| easyjson* | large | 262 | 25 | 2879 |
| | | | | |
| ffjson | regular | 122 | 153 | 21340 |
| ffjson** | regular | 146 | 152 | 4897 |
| ffjson | small | 36 | 5 | 384 |
| ffjson** | small | 64 | 4 | 128 |
| ffjson | large | 134 | 7317 | 818k |
| ffjson** | large | 125 | 7320 | 827k |
| | | | | |
| codec | regular | 80 | 17 | 33601 |
| codec*** | regular | 108 | 9 | 1153 |
| codec | small | 42 | 3 | 304 |
| codec*** | small | 56 | 1 | 48 |
| codec | large | 73 | 483 | 2.5M |
| codec*** | large | 103 | 451 | 66007 |
| | | | | |
| ujson | regular | 92 | N/A | N/A |
\* marshaling to a writer,
\*\* using `ffjson.Pool()`,
\*\*\* reusing output slice instead of resetting it to nil
#### Marshaling, concurrent.
| lib | json size | MB/s | allocs/op | B/op |
|:----------|:----------|-----:|----------:|------:|
| standard | regular | 252 | 9 | 23257 |
| standard | small | 124 | 3 | 328 |
| standard | large | 289 | 17 | 1.2M |
| | | | | |
| easyjson | regular | 792 | 9 | 10597 |
| easyjson* | regular | 1748 | 8 | 779 |
| easyjson | small | 333 | 1 | 128 |
| easyjson | large | 718 | 36 | 548k |
| easyjson* | large | 2134 | 25 | 4957 |
| | | | | |
| ffjson | regular | 301 | 153 | 21629 |
| ffjson** | regular | 707 | 152 | 5148 |
| ffjson | small | 62 | 5 | 384 |
| ffjson** | small | 282 | 4 | 128 |
| ffjson | large | 438 | 7330 | 1.0M |
| ffjson** | large | 131 | 7319 | 820k |
| | | | | |
| codec | regular | 183 | 17 | 33603 |
| codec*** | regular | 671 | 9 | 1157 |
| codec | small | 147 | 3 | 304 |
| codec*** | small | 299 | 1 | 48 |
| codec | large | 190 | 483 | 2.5M |
| codec*** | large | 752 | 451 | 77574 |
\* marshaling to a writer,
\*\* using `ffjson.Pool()`,
\*\*\* reusing output slice instead of resetting it to nil

View file

@ -0,0 +1,279 @@
// +build use_codec
package benchmark
import (
"testing"
"github.com/ugorji/go/codec"
)
func BenchmarkCodec_Unmarshal_M(b *testing.B) {
var h codec.Handle = new(codec.JsonHandle)
dec := codec.NewDecoderBytes(nil, h)
b.SetBytes(int64(len(largeStructText)))
for i := 0; i < b.N; i++ {
var s LargeStruct
dec.ResetBytes(largeStructText)
if err := dec.Decode(&s); err != nil {
b.Error(err)
}
}
}
func BenchmarkCodec_Unmarshal_S(b *testing.B) {
var h codec.Handle = new(codec.JsonHandle)
dec := codec.NewDecoderBytes(nil, h)
b.SetBytes(int64(len(smallStructText)))
for i := 0; i < b.N; i++ {
var s LargeStruct
dec.ResetBytes(smallStructText)
if err := dec.Decode(&s); err != nil {
b.Error(err)
}
}
}
func BenchmarkCodec_Marshal_S(b *testing.B) {
var h codec.Handle = new(codec.JsonHandle)
var out []byte
enc := codec.NewEncoderBytes(&out, h)
var l int64
for i := 0; i < b.N; i++ {
enc.ResetBytes(&out)
if err := enc.Encode(&smallStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = nil
}
b.SetBytes(l)
}
func BenchmarkCodec_Marshal_M(b *testing.B) {
var h codec.Handle = new(codec.JsonHandle)
var out []byte
enc := codec.NewEncoderBytes(&out, h)
var l int64
for i := 0; i < b.N; i++ {
enc.ResetBytes(&out)
if err := enc.Encode(&largeStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = nil
}
b.SetBytes(l)
}
func BenchmarkCodec_Marshal_L(b *testing.B) {
var h codec.Handle = new(codec.JsonHandle)
var out []byte
enc := codec.NewEncoderBytes(&out, h)
var l int64
for i := 0; i < b.N; i++ {
enc.ResetBytes(&out)
if err := enc.Encode(&xlStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = nil
}
b.SetBytes(l)
}
func BenchmarkCodec_Marshal_S_Reuse(b *testing.B) {
var h codec.Handle = new(codec.JsonHandle)
var out []byte
enc := codec.NewEncoderBytes(&out, h)
var l int64
for i := 0; i < b.N; i++ {
enc.ResetBytes(&out)
if err := enc.Encode(&smallStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = out[:0]
}
b.SetBytes(l)
}
func BenchmarkCodec_Marshal_M_Reuse(b *testing.B) {
var h codec.Handle = new(codec.JsonHandle)
var out []byte
enc := codec.NewEncoderBytes(&out, h)
var l int64
for i := 0; i < b.N; i++ {
enc.ResetBytes(&out)
if err := enc.Encode(&largeStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = out[:0]
}
b.SetBytes(l)
}
func BenchmarkCodec_Marshal_L_Reuse(b *testing.B) {
var h codec.Handle = new(codec.JsonHandle)
var out []byte
enc := codec.NewEncoderBytes(&out, h)
var l int64
for i := 0; i < b.N; i++ {
enc.ResetBytes(&out)
if err := enc.Encode(&xlStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = out[:0]
}
b.SetBytes(l)
}
func BenchmarkCodec_Marshal_S_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
var out []byte
var h codec.Handle = new(codec.JsonHandle)
enc := codec.NewEncoderBytes(&out, h)
for pb.Next() {
enc.ResetBytes(&out)
if err := enc.Encode(&smallStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = nil
}
})
b.SetBytes(l)
}
func BenchmarkCodec_Marshal_M_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
var h codec.Handle = new(codec.JsonHandle)
var out []byte
enc := codec.NewEncoderBytes(&out, h)
for pb.Next() {
enc.ResetBytes(&out)
if err := enc.Encode(&largeStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = nil
}
})
b.SetBytes(l)
}
func BenchmarkCodec_Marshal_L_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
var h codec.Handle = new(codec.JsonHandle)
var out []byte
enc := codec.NewEncoderBytes(&out, h)
for pb.Next() {
enc.ResetBytes(&out)
if err := enc.Encode(&xlStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = nil
}
})
b.SetBytes(l)
}
func BenchmarkCodec_Marshal_S_Parallel_Reuse(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
var out []byte
var h codec.Handle = new(codec.JsonHandle)
enc := codec.NewEncoderBytes(&out, h)
for pb.Next() {
enc.ResetBytes(&out)
if err := enc.Encode(&smallStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = out[:0]
}
})
b.SetBytes(l)
}
func BenchmarkCodec_Marshal_M_Parallel_Reuse(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
var h codec.Handle = new(codec.JsonHandle)
var out []byte
enc := codec.NewEncoderBytes(&out, h)
for pb.Next() {
enc.ResetBytes(&out)
if err := enc.Encode(&largeStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = out[:0]
}
})
b.SetBytes(l)
}
func BenchmarkCodec_Marshal_L_Parallel_Reuse(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
var h codec.Handle = new(codec.JsonHandle)
var out []byte
enc := codec.NewEncoderBytes(&out, h)
for pb.Next() {
enc.ResetBytes(&out)
if err := enc.Encode(&xlStructData); err != nil {
b.Error(err)
}
l = int64(len(out))
out = out[:0]
}
})
b.SetBytes(l)
}

148
vendor/github.com/mailru/easyjson/benchmark/data.go generated vendored Normal file
View file

@ -0,0 +1,148 @@
// Package benchmark provides a simple benchmark for easyjson against default serialization and ffjson.
// The data example is taken from https://dev.twitter.com/rest/reference/get/search/tweets
package benchmark
import (
"io/ioutil"
)
var largeStructText, _ = ioutil.ReadFile("example.json")
var xlStructData XLStruct
func init() {
for i := 0; i < 50; i++ {
xlStructData.Data = append(xlStructData.Data, largeStructData)
}
}
var smallStructText = []byte(`{"hashtags":[{"indices":[5, 10],"text":"some-text"}],"urls":[],"user_mentions":[]}`)
var smallStructData = Entities{
Hashtags: []Hashtag{{Indices: []int{5, 10}, Text: "some-text"}},
Urls: []*string{},
UserMentions: []*string{},
}
type SearchMetadata struct {
CompletedIn float64 `json:"completed_in"`
Count int `json:"count"`
MaxID int `json:"max_id"`
MaxIDStr string `json:"max_id_str"`
NextResults string `json:"next_results"`
Query string `json:"query"`
RefreshURL string `json:"refresh_url"`
SinceID int `json:"since_id"`
SinceIDStr string `json:"since_id_str"`
}
type Hashtag struct {
Indices []int `json:"indices"`
Text string `json:"text"`
}
//easyjson:json
type Entities struct {
Hashtags []Hashtag `json:"hashtags"`
Urls []*string `json:"urls"`
UserMentions []*string `json:"user_mentions"`
}
type UserEntityDescription struct {
Urls []*string `json:"urls"`
}
type URL struct {
ExpandedURL *string `json:"expanded_url"`
Indices []int `json:"indices"`
URL string `json:"url"`
}
type UserEntityURL struct {
Urls []URL `json:"urls"`
}
type UserEntities struct {
Description UserEntityDescription `json:"description"`
URL UserEntityURL `json:"url"`
}
type User struct {
ContributorsEnabled bool `json:"contributors_enabled"`
CreatedAt string `json:"created_at"`
DefaultProfile bool `json:"default_profile"`
DefaultProfileImage bool `json:"default_profile_image"`
Description string `json:"description"`
Entities UserEntities `json:"entities"`
FavouritesCount int `json:"favourites_count"`
FollowRequestSent *string `json:"follow_request_sent"`
FollowersCount int `json:"followers_count"`
Following *string `json:"following"`
FriendsCount int `json:"friends_count"`
GeoEnabled bool `json:"geo_enabled"`
ID int `json:"id"`
IDStr string `json:"id_str"`
IsTranslator bool `json:"is_translator"`
Lang string `json:"lang"`
ListedCount int `json:"listed_count"`
Location string `json:"location"`
Name string `json:"name"`
Notifications *string `json:"notifications"`
ProfileBackgroundColor string `json:"profile_background_color"`
ProfileBackgroundImageURL string `json:"profile_background_image_url"`
ProfileBackgroundImageURLHTTPS string `json:"profile_background_image_url_https"`
ProfileBackgroundTile bool `json:"profile_background_tile"`
ProfileImageURL string `json:"profile_image_url"`
ProfileImageURLHTTPS string `json:"profile_image_url_https"`
ProfileLinkColor string `json:"profile_link_color"`
ProfileSidebarBorderColor string `json:"profile_sidebar_border_color"`
ProfileSidebarFillColor string `json:"profile_sidebar_fill_color"`
ProfileTextColor string `json:"profile_text_color"`
ProfileUseBackgroundImage bool `json:"profile_use_background_image"`
Protected bool `json:"protected"`
ScreenName string `json:"screen_name"`
ShowAllInlineMedia bool `json:"show_all_inline_media"`
StatusesCount int `json:"statuses_count"`
TimeZone string `json:"time_zone"`
URL *string `json:"url"`
UtcOffset int `json:"utc_offset"`
Verified bool `json:"verified"`
}
type StatusMetadata struct {
IsoLanguageCode string `json:"iso_language_code"`
ResultType string `json:"result_type"`
}
type Status struct {
Contributors *string `json:"contributors"`
Coordinates *string `json:"coordinates"`
CreatedAt string `json:"created_at"`
Entities Entities `json:"entities"`
Favorited bool `json:"favorited"`
Geo *string `json:"geo"`
ID int64 `json:"id"`
IDStr string `json:"id_str"`
InReplyToScreenName *string `json:"in_reply_to_screen_name"`
InReplyToStatusID *string `json:"in_reply_to_status_id"`
InReplyToStatusIDStr *string `json:"in_reply_to_status_id_str"`
InReplyToUserID *string `json:"in_reply_to_user_id"`
InReplyToUserIDStr *string `json:"in_reply_to_user_id_str"`
Metadata StatusMetadata `json:"metadata"`
Place *string `json:"place"`
RetweetCount int `json:"retweet_count"`
Retweeted bool `json:"retweeted"`
Source string `json:"source"`
Text string `json:"text"`
Truncated bool `json:"truncated"`
User User `json:"user"`
}
//easyjson:json
type LargeStruct struct {
SearchMetadata SearchMetadata `json:"search_metadata"`
Statuses []Status `json:"statuses"`
}
//easyjson:json
type XLStruct struct {
Data []LargeStruct
}

6914
vendor/github.com/mailru/easyjson/benchmark/data_codec.go generated vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

350
vendor/github.com/mailru/easyjson/benchmark/data_var.go generated vendored Normal file
View file

@ -0,0 +1,350 @@
package benchmark
var largeStructData = LargeStruct{
SearchMetadata: SearchMetadata{
CompletedIn: 0.035,
Count: 4,
MaxID: 250126199840518145,
MaxIDStr: "250126199840518145",
NextResults: "?max_id=249279667666817023&q=%23freebandnames&count=4&include_entities=1&result_type=mixed",
Query: "%23freebandnames",
RefreshURL: "?since_id=250126199840518145&q=%23freebandnames&result_type=mixed&include_entities=1",
SinceID: 24012619984051000,
SinceIDStr: "24012619984051000",
},
Statuses: []Status{
{
Contributors: nil,
Coordinates: nil,
CreatedAt: "Mon Sep 24 03:35:21 +0000 2012",
Entities: Entities{
Hashtags: []Hashtag{{
Indices: []int{20, 34},
Text: "freebandnames"},
},
Urls: []*string{},
UserMentions: []*string{},
},
Favorited: false,
Geo: nil,
ID: 250075927172759552,
IDStr: "250075927172759552",
InReplyToScreenName: nil,
InReplyToStatusID: nil,
InReplyToStatusIDStr: nil,
InReplyToUserID: nil,
InReplyToUserIDStr: nil,
Metadata: StatusMetadata{
IsoLanguageCode: "en",
ResultType: "recent",
},
Place: nil,
RetweetCount: 0,
Retweeted: false,
Source: "<a href=\"//itunes.apple.com/us/app/twitter/id409789998?mt=12%5C%22\" rel=\"\\\"nofollow\\\"\">Twitter for Mac</a>",
Text: "Aggressive Ponytail #freebandnames",
Truncated: false,
User: User{
ContributorsEnabled: false,
CreatedAt: "Mon Apr 26 06:01:55 +0000 2010",
DefaultProfile: true,
DefaultProfileImage: false,
Description: "Born 330 Live 310",
Entities: UserEntities{
Description: UserEntityDescription{
Urls: []*string{},
},
URL: UserEntityURL{
Urls: []URL{{
ExpandedURL: nil,
Indices: []int{0, 0},
URL: "",
}},
},
},
FavouritesCount: 0,
FollowRequestSent: nil,
FollowersCount: 70,
Following: nil,
FriendsCount: 110,
GeoEnabled: true,
ID: 137238150,
IDStr: "137238150",
IsTranslator: false,
Lang: "en",
ListedCount: 2,
Location: "LA, CA",
Name: "Sean Cummings",
Notifications: nil,
ProfileBackgroundColor: "C0DEED",
ProfileBackgroundImageURL: "http://a0.twimg.com/images/themes/theme1/bg.png",
ProfileBackgroundImageURLHTTPS: "https://si0.twimg.com/images/themes/theme1/bg.png",
ProfileBackgroundTile: false,
ProfileImageURL: "http://a0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg",
ProfileImageURLHTTPS: "https://si0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg",
ProfileLinkColor: "0084B4",
ProfileSidebarBorderColor: "C0DEED",
ProfileSidebarFillColor: "DDEEF6",
ProfileTextColor: "333333",
ProfileUseBackgroundImage: true,
Protected: false,
ScreenName: "sean_cummings",
ShowAllInlineMedia: false,
StatusesCount: 579,
TimeZone: "Pacific Time (US & Canada)",
URL: nil,
UtcOffset: -28800,
Verified: false,
},
},
{
Contributors: nil,
Coordinates: nil,
CreatedAt: "Fri Sep 21 23:40:54 +0000 2012",
Entities: Entities{
Hashtags: []Hashtag{{
Indices: []int{20, 34},
Text: "FreeBandNames",
}},
Urls: []*string{},
UserMentions: []*string{},
},
Favorited: false,
Geo: nil,
ID: 249292149810667520,
IDStr: "249292149810667520",
InReplyToScreenName: nil,
InReplyToStatusID: nil,
InReplyToStatusIDStr: nil,
InReplyToUserID: nil,
InReplyToUserIDStr: nil,
Metadata: StatusMetadata{
IsoLanguageCode: "pl",
ResultType: "recent",
},
Place: nil,
RetweetCount: 0,
Retweeted: false,
Source: "web",
Text: "Thee Namaste Nerdz. #FreeBandNames",
Truncated: false,
User: User{
ContributorsEnabled: false,
CreatedAt: "Tue Apr 07 19:05:07 +0000 2009",
DefaultProfile: false,
DefaultProfileImage: false,
Description: "You will come to Durham, North Carolina. I will sell you some records then, here in Durham, North Carolina. Fun will happen.",
Entities: UserEntities{
Description: UserEntityDescription{Urls: []*string{}},
URL: UserEntityURL{
Urls: []URL{{
ExpandedURL: nil,
Indices: []int{0, 32},
URL: "http://bullcityrecords.com/wnng/"}},
},
},
FavouritesCount: 8,
FollowRequestSent: nil,
FollowersCount: 2052,
Following: nil,
FriendsCount: 348,
GeoEnabled: false,
ID: 29516238,
IDStr: "29516238",
IsTranslator: false,
Lang: "en",
ListedCount: 118,
Location: "Durham, NC",
Name: "Chaz Martenstein",
Notifications: nil,
ProfileBackgroundColor: "9AE4E8",
ProfileBackgroundImageURL: "http://a0.twimg.com/profile_background_images/9423277/background_tile.bmp",
ProfileBackgroundImageURLHTTPS: "https://si0.twimg.com/profile_background_images/9423277/background_tile.bmp",
ProfileBackgroundTile: true,
ProfileImageURL: "http://a0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg",
ProfileImageURLHTTPS: "https://si0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg",
ProfileLinkColor: "0084B4",
ProfileSidebarBorderColor: "BDDCAD",
ProfileSidebarFillColor: "DDFFCC",
ProfileTextColor: "333333",
ProfileUseBackgroundImage: true,
Protected: false,
ScreenName: "bullcityrecords",
ShowAllInlineMedia: true,
StatusesCount: 7579,
TimeZone: "Eastern Time (US & Canada)",
URL: nil,
UtcOffset: -18000,
Verified: false,
},
},
Status{
Contributors: nil,
Coordinates: nil,
CreatedAt: "Fri Sep 21 23:30:20 +0000 2012",
Entities: Entities{
Hashtags: []Hashtag{{
Indices: []int{29, 43},
Text: "freebandnames",
}},
Urls: []*string{},
UserMentions: []*string{},
},
Favorited: false,
Geo: nil,
ID: 249289491129438208,
IDStr: "249289491129438208",
InReplyToScreenName: nil,
InReplyToStatusID: nil,
InReplyToStatusIDStr: nil,
InReplyToUserID: nil,
InReplyToUserIDStr: nil,
Metadata: StatusMetadata{
IsoLanguageCode: "en",
ResultType: "recent",
},
Place: nil,
RetweetCount: 0,
Retweeted: false,
Source: "web",
Text: "Mexican Heaven, Mexican Hell #freebandnames",
Truncated: false,
User: User{
ContributorsEnabled: false,
CreatedAt: "Tue Sep 01 21:21:35 +0000 2009",
DefaultProfile: false,
DefaultProfileImage: false,
Description: "Science Fiction Writer, sort of. Likes Superheroes, Mole People, Alt. Timelines.",
Entities: UserEntities{
Description: UserEntityDescription{
Urls: nil,
},
URL: UserEntityURL{
Urls: []URL{{
ExpandedURL: nil,
Indices: []int{0, 0},
URL: "",
}},
},
},
FavouritesCount: 19,
FollowRequestSent: nil,
FollowersCount: 63,
Following: nil,
FriendsCount: 63,
GeoEnabled: false,
ID: 70789458,
IDStr: "70789458",
IsTranslator: false,
Lang: "en",
ListedCount: 1,
Location: "Kingston New York",
Name: "Thomas John Wakeman",
Notifications: nil,
ProfileBackgroundColor: "352726",
ProfileBackgroundImageURL: "http://a0.twimg.com/images/themes/theme5/bg.gif",
ProfileBackgroundImageURLHTTPS: "https://si0.twimg.com/images/themes/theme5/bg.gif",
ProfileBackgroundTile: false,
ProfileImageURL: "http://a0.twimg.com/profile_images/2219333930/Froggystyle_normal.png",
ProfileImageURLHTTPS: "https://si0.twimg.com/profile_images/2219333930/Froggystyle_normal.png",
ProfileLinkColor: "D02B55",
ProfileSidebarBorderColor: "829D5E",
ProfileSidebarFillColor: "99CC33",
ProfileTextColor: "3E4415",
ProfileUseBackgroundImage: true,
Protected: false,
ScreenName: "MonkiesFist",
ShowAllInlineMedia: false,
StatusesCount: 1048,
TimeZone: "Eastern Time (US & Canada)",
URL: nil,
UtcOffset: -18000,
Verified: false,
},
},
Status{
Contributors: nil,
Coordinates: nil,
CreatedAt: "Fri Sep 21 22:51:18 +0000 2012",
Entities: Entities{
Hashtags: []Hashtag{{
Indices: []int{20, 34},
Text: "freebandnames",
}},
Urls: []*string{},
UserMentions: []*string{},
},
Favorited: false,
Geo: nil,
ID: 249279667666817024,
IDStr: "249279667666817024",
InReplyToScreenName: nil,
InReplyToStatusID: nil,
InReplyToStatusIDStr: nil,
InReplyToUserID: nil,
InReplyToUserIDStr: nil,
Metadata: StatusMetadata{
IsoLanguageCode: "en",
ResultType: "recent",
},
Place: nil,
RetweetCount: 0,
Retweeted: false,
Source: "<a href=\"//twitter.com/download/iphone%5C%22\" rel=\"\\\"nofollow\\\"\">Twitter for iPhone</a>",
Text: "The Foolish Mortals #freebandnames",
Truncated: false,
User: User{
ContributorsEnabled: false,
CreatedAt: "Mon May 04 00:05:00 +0000 2009",
DefaultProfile: false,
DefaultProfileImage: false,
Description: "Cartoonist, Illustrator, and T-Shirt connoisseur",
Entities: UserEntities{
Description: UserEntityDescription{
Urls: []*string{},
},
URL: UserEntityURL{
Urls: []URL{{
ExpandedURL: nil,
Indices: []int{0, 24},
URL: "http://www.omnitarian.me",
}},
},
},
FavouritesCount: 647,
FollowRequestSent: nil,
FollowersCount: 608,
Following: nil,
FriendsCount: 249,
GeoEnabled: false,
ID: 37539828,
IDStr: "37539828",
IsTranslator: false,
Lang: "en",
ListedCount: 52,
Location: "Wisconsin, USA",
Name: "Marty Elmer",
Notifications: nil,
ProfileBackgroundColor: "EEE3C4",
ProfileBackgroundImageURL: "http://a0.twimg.com/profile_background_images/106455659/rect6056-9.png",
ProfileBackgroundImageURLHTTPS: "https://si0.twimg.com/profile_background_images/106455659/rect6056-9.png",
ProfileBackgroundTile: true,
ProfileImageURL: "http://a0.twimg.com/profile_images/1629790393/shrinker_2000_trans_normal.png",
ProfileImageURLHTTPS: "https://si0.twimg.com/profile_images/1629790393/shrinker_2000_trans_normal.png",
ProfileLinkColor: "3B2A26",
ProfileSidebarBorderColor: "615A44",
ProfileSidebarFillColor: "BFAC83",
ProfileTextColor: "000000",
ProfileUseBackgroundImage: true,
Protected: false,
ScreenName: "Omnitarian",
ShowAllInlineMedia: true,
StatusesCount: 3575,
TimeZone: "Central Time (US & Canada)",
URL: nil,
UtcOffset: -21600,
Verified: false,
},
},
},
}

View file

@ -0,0 +1,118 @@
// +build !use_easyjson,!use_ffjson,!use_codec
package benchmark
import (
"encoding/json"
"testing"
)
func BenchmarkStd_Unmarshal_M(b *testing.B) {
b.SetBytes(int64(len(largeStructText)))
for i := 0; i < b.N; i++ {
var s LargeStruct
err := json.Unmarshal(largeStructText, &s)
if err != nil {
b.Error(err)
}
}
}
func BenchmarkStd_Unmarshal_S(b *testing.B) {
for i := 0; i < b.N; i++ {
var s Entities
err := json.Unmarshal(smallStructText, &s)
if err != nil {
b.Error(err)
}
}
b.SetBytes(int64(len(smallStructText)))
}
func BenchmarkStd_Marshal_M(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := json.Marshal(&largeStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
b.SetBytes(l)
}
func BenchmarkStd_Marshal_L(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := json.Marshal(&xlStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
b.SetBytes(l)
}
func BenchmarkStd_Marshal_M_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
data, err := json.Marshal(&largeStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
})
b.SetBytes(l)
}
func BenchmarkStd_Marshal_L_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
data, err := json.Marshal(&xlStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
})
b.SetBytes(l)
}
func BenchmarkStd_Marshal_S(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := json.Marshal(&smallStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
b.SetBytes(l)
}
func BenchmarkStd_Marshal_S_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
data, err := json.Marshal(&smallStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
})
b.SetBytes(l)
}
func BenchmarkStd_Marshal_M_ToWriter(b *testing.B) {
enc := json.NewEncoder(&DummyWriter{})
for i := 0; i < b.N; i++ {
err := enc.Encode(&largeStructData)
if err != nil {
b.Error(err)
}
}
}

View file

@ -0,0 +1,11 @@
package benchmark
import (
"testing"
)
type DummyWriter struct{}
func (w DummyWriter) Write(data []byte) (int, error) { return len(data), nil }
func TestToSuppressNoTestsWarning(t *testing.T) {}

View file

@ -0,0 +1,184 @@
// +build use_easyjson
package benchmark
import (
"testing"
"github.com/mailru/easyjson"
"github.com/mailru/easyjson/jwriter"
)
func BenchmarkEJ_Unmarshal_M(b *testing.B) {
b.SetBytes(int64(len(largeStructText)))
for i := 0; i < b.N; i++ {
var s LargeStruct
err := s.UnmarshalJSON(largeStructText)
if err != nil {
b.Error(err)
}
}
}
func BenchmarkEJ_Unmarshal_S(b *testing.B) {
b.SetBytes(int64(len(smallStructText)))
for i := 0; i < b.N; i++ {
var s Entities
err := s.UnmarshalJSON(smallStructText)
if err != nil {
b.Error(err)
}
}
}
func BenchmarkEJ_Marshal_M(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := easyjson.Marshal(&largeStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
b.SetBytes(l)
}
func BenchmarkEJ_Marshal_L(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := easyjson.Marshal(&xlStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
b.SetBytes(l)
}
func BenchmarkEJ_Marshal_L_ToWriter(b *testing.B) {
var l int64
out := &DummyWriter{}
for i := 0; i < b.N; i++ {
w := jwriter.Writer{}
xlStructData.MarshalEasyJSON(&w)
if w.Error != nil {
b.Error(w.Error)
}
l = int64(w.Size())
w.DumpTo(out)
}
b.SetBytes(l)
}
func BenchmarkEJ_Marshal_M_Parallel(b *testing.B) {
b.SetBytes(int64(len(largeStructText)))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err := largeStructData.MarshalJSON()
if err != nil {
b.Error(err)
}
}
})
}
func BenchmarkEJ_Marshal_M_ToWriter(b *testing.B) {
var l int64
out := &DummyWriter{}
for i := 0; i < b.N; i++ {
w := jwriter.Writer{}
largeStructData.MarshalEasyJSON(&w)
if w.Error != nil {
b.Error(w.Error)
}
l = int64(w.Size())
w.DumpTo(out)
}
b.SetBytes(l)
}
func BenchmarkEJ_Marshal_M_ToWriter_Parallel(b *testing.B) {
out := &DummyWriter{}
b.RunParallel(func(pb *testing.PB) {
var l int64
for pb.Next() {
w := jwriter.Writer{}
largeStructData.MarshalEasyJSON(&w)
if w.Error != nil {
b.Error(w.Error)
}
l = int64(w.Size())
w.DumpTo(out)
}
if l > 0 {
b.SetBytes(l)
}
})
}
func BenchmarkEJ_Marshal_L_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
data, err := xlStructData.MarshalJSON()
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
})
b.SetBytes(l)
}
func BenchmarkEJ_Marshal_L_ToWriter_Parallel(b *testing.B) {
out := &DummyWriter{}
b.RunParallel(func(pb *testing.PB) {
var l int64
for pb.Next() {
w := jwriter.Writer{}
xlStructData.MarshalEasyJSON(&w)
if w.Error != nil {
b.Error(w.Error)
}
l = int64(w.Size())
w.DumpTo(out)
}
if l > 0 {
b.SetBytes(l)
}
})
}
func BenchmarkEJ_Marshal_S(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := smallStructData.MarshalJSON()
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
b.SetBytes(l)
}
func BenchmarkEJ_Marshal_S_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
data, err := smallStructData.MarshalJSON()
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
})
b.SetBytes(l)
}

View file

@ -0,0 +1,415 @@
{
"statuses": [
{
"coordinates": null,
"favorited": false,
"truncated": false,
"created_at": "Mon Sep 24 03:35:21 +0000 2012",
"id_str": "250075927172759552",
"entities": {
"urls": [
],
"hashtags": [
{
"text": "freebandnames",
"indices": [
20,
34
]
}
],
"user_mentions": [
]
},
"in_reply_to_user_id_str": null,
"contributors": null,
"text": "Aggressive Ponytail #freebandnames",
"metadata": {
"iso_language_code": "en",
"result_type": "recent"
},
"retweet_count": 0,
"in_reply_to_status_id_str": null,
"id": 250075927172759552,
"geo": null,
"retweeted": false,
"in_reply_to_user_id": null,
"place": null,
"user": {
"profile_sidebar_fill_color": "DDEEF6",
"profile_sidebar_border_color": "C0DEED",
"profile_background_tile": false,
"name": "Sean Cummings",
"profile_image_url": "http://a0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg",
"created_at": "Mon Apr 26 06:01:55 +0000 2010",
"location": "LA, CA",
"follow_request_sent": null,
"profile_link_color": "0084B4",
"is_translator": false,
"id_str": "137238150",
"entities": {
"url": {
"urls": [
{
"expanded_url": null,
"url": "",
"indices": [
0,
0
]
}
]
},
"description": {
"urls": [
]
}
},
"default_profile": true,
"contributors_enabled": false,
"favourites_count": 0,
"url": null,
"profile_image_url_https": "https://si0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg",
"utc_offset": -28800,
"id": 137238150,
"profile_use_background_image": true,
"listed_count": 2,
"profile_text_color": "333333",
"lang": "en",
"followers_count": 70,
"protected": false,
"notifications": null,
"profile_background_image_url_https": "https://si0.twimg.com/images/themes/theme1/bg.png",
"profile_background_color": "C0DEED",
"verified": false,
"geo_enabled": true,
"time_zone": "Pacific Time (US & Canada)",
"description": "Born 330 Live 310",
"default_profile_image": false,
"profile_background_image_url": "http://a0.twimg.com/images/themes/theme1/bg.png",
"statuses_count": 579,
"friends_count": 110,
"following": null,
"show_all_inline_media": false,
"screen_name": "sean_cummings"
},
"in_reply_to_screen_name": null,
"source": "<a href=\"//itunes.apple.com/us/app/twitter/id409789998?mt=12%5C%22\" rel=\"\\\"nofollow\\\"\">Twitter for Mac</a>",
"in_reply_to_status_id": null
},
{
"coordinates": null,
"favorited": false,
"truncated": false,
"created_at": "Fri Sep 21 23:40:54 +0000 2012",
"id_str": "249292149810667520",
"entities": {
"urls": [
],
"hashtags": [
{
"text": "FreeBandNames",
"indices": [
20,
34
]
}
],
"user_mentions": [
]
},
"in_reply_to_user_id_str": null,
"contributors": null,
"text": "Thee Namaste Nerdz. #FreeBandNames",
"metadata": {
"iso_language_code": "pl",
"result_type": "recent"
},
"retweet_count": 0,
"in_reply_to_status_id_str": null,
"id": 249292149810667520,
"geo": null,
"retweeted": false,
"in_reply_to_user_id": null,
"place": null,
"user": {
"profile_sidebar_fill_color": "DDFFCC",
"profile_sidebar_border_color": "BDDCAD",
"profile_background_tile": true,
"name": "Chaz Martenstein",
"profile_image_url": "http://a0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg",
"created_at": "Tue Apr 07 19:05:07 +0000 2009",
"location": "Durham, NC",
"follow_request_sent": null,
"profile_link_color": "0084B4",
"is_translator": false,
"id_str": "29516238",
"entities": {
"url": {
"urls": [
{
"expanded_url": null,
"url": "http://bullcityrecords.com/wnng/",
"indices": [
0,
32
]
}
]
},
"description": {
"urls": [
]
}
},
"default_profile": false,
"contributors_enabled": false,
"favourites_count": 8,
"url": "http://bullcityrecords.com/wnng/",
"profile_image_url_https": "https://si0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg",
"utc_offset": -18000,
"id": 29516238,
"profile_use_background_image": true,
"listed_count": 118,
"profile_text_color": "333333",
"lang": "en",
"followers_count": 2052,
"protected": false,
"notifications": null,
"profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/9423277/background_tile.bmp",
"profile_background_color": "9AE4E8",
"verified": false,
"geo_enabled": false,
"time_zone": "Eastern Time (US & Canada)",
"description": "You will come to Durham, North Carolina. I will sell you some records then, here in Durham, North Carolina. Fun will happen.",
"default_profile_image": false,
"profile_background_image_url": "http://a0.twimg.com/profile_background_images/9423277/background_tile.bmp",
"statuses_count": 7579,
"friends_count": 348,
"following": null,
"show_all_inline_media": true,
"screen_name": "bullcityrecords"
},
"in_reply_to_screen_name": null,
"source": "web",
"in_reply_to_status_id": null
},
{
"coordinates": null,
"favorited": false,
"truncated": false,
"created_at": "Fri Sep 21 23:30:20 +0000 2012",
"id_str": "249289491129438208",
"entities": {
"urls": [
],
"hashtags": [
{
"text": "freebandnames",
"indices": [
29,
43
]
}
],
"user_mentions": [
]
},
"in_reply_to_user_id_str": null,
"contributors": null,
"text": "Mexican Heaven, Mexican Hell #freebandnames",
"metadata": {
"iso_language_code": "en",
"result_type": "recent"
},
"retweet_count": 0,
"in_reply_to_status_id_str": null,
"id": 249289491129438208,
"geo": null,
"retweeted": false,
"in_reply_to_user_id": null,
"place": null,
"user": {
"profile_sidebar_fill_color": "99CC33",
"profile_sidebar_border_color": "829D5E",
"profile_background_tile": false,
"name": "Thomas John Wakeman",
"profile_image_url": "http://a0.twimg.com/profile_images/2219333930/Froggystyle_normal.png",
"created_at": "Tue Sep 01 21:21:35 +0000 2009",
"location": "Kingston New York",
"follow_request_sent": null,
"profile_link_color": "D02B55",
"is_translator": false,
"id_str": "70789458",
"entities": {
"url": {
"urls": [
{
"expanded_url": null,
"url": "",
"indices": [
0,
0
]
}
]
},
"description": {
"urls": [
]
}
},
"default_profile": false,
"contributors_enabled": false,
"favourites_count": 19,
"url": null,
"profile_image_url_https": "https://si0.twimg.com/profile_images/2219333930/Froggystyle_normal.png",
"utc_offset": -18000,
"id": 70789458,
"profile_use_background_image": true,
"listed_count": 1,
"profile_text_color": "3E4415",
"lang": "en",
"followers_count": 63,
"protected": false,
"notifications": null,
"profile_background_image_url_https": "https://si0.twimg.com/images/themes/theme5/bg.gif",
"profile_background_color": "352726",
"verified": false,
"geo_enabled": false,
"time_zone": "Eastern Time (US & Canada)",
"description": "Science Fiction Writer, sort of. Likes Superheroes, Mole People, Alt. Timelines.",
"default_profile_image": false,
"profile_background_image_url": "http://a0.twimg.com/images/themes/theme5/bg.gif",
"statuses_count": 1048,
"friends_count": 63,
"following": null,
"show_all_inline_media": false,
"screen_name": "MonkiesFist"
},
"in_reply_to_screen_name": null,
"source": "web",
"in_reply_to_status_id": null
},
{
"coordinates": null,
"favorited": false,
"truncated": false,
"created_at": "Fri Sep 21 22:51:18 +0000 2012",
"id_str": "249279667666817024",
"entities": {
"urls": [
],
"hashtags": [
{
"text": "freebandnames",
"indices": [
20,
34
]
}
],
"user_mentions": [
]
},
"in_reply_to_user_id_str": null,
"contributors": null,
"text": "The Foolish Mortals #freebandnames",
"metadata": {
"iso_language_code": "en",
"result_type": "recent"
},
"retweet_count": 0,
"in_reply_to_status_id_str": null,
"id": 249279667666817024,
"geo": null,
"retweeted": false,
"in_reply_to_user_id": null,
"place": null,
"user": {
"profile_sidebar_fill_color": "BFAC83",
"profile_sidebar_border_color": "615A44",
"profile_background_tile": true,
"name": "Marty Elmer",
"profile_image_url": "http://a0.twimg.com/profile_images/1629790393/shrinker_2000_trans_normal.png",
"created_at": "Mon May 04 00:05:00 +0000 2009",
"location": "Wisconsin, USA",
"follow_request_sent": null,
"profile_link_color": "3B2A26",
"is_translator": false,
"id_str": "37539828",
"entities": {
"url": {
"urls": [
{
"expanded_url": null,
"url": "http://www.omnitarian.me",
"indices": [
0,
24
]
}
]
},
"description": {
"urls": [
]
}
},
"default_profile": false,
"contributors_enabled": false,
"favourites_count": 647,
"url": "http://www.omnitarian.me",
"profile_image_url_https": "https://si0.twimg.com/profile_images/1629790393/shrinker_2000_trans_normal.png",
"utc_offset": -21600,
"id": 37539828,
"profile_use_background_image": true,
"listed_count": 52,
"profile_text_color": "000000",
"lang": "en",
"followers_count": 608,
"protected": false,
"notifications": null,
"profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/106455659/rect6056-9.png",
"profile_background_color": "EEE3C4",
"verified": false,
"geo_enabled": false,
"time_zone": "Central Time (US & Canada)",
"description": "Cartoonist, Illustrator, and T-Shirt connoisseur",
"default_profile_image": false,
"profile_background_image_url": "http://a0.twimg.com/profile_background_images/106455659/rect6056-9.png",
"statuses_count": 3575,
"friends_count": 249,
"following": null,
"show_all_inline_media": true,
"screen_name": "Omnitarian"
},
"in_reply_to_screen_name": null,
"source": "<a href=\"//twitter.com/download/iphone%5C%22\" rel=\"\\\"nofollow\\\"\">Twitter for iPhone</a>",
"in_reply_to_status_id": null
}
],
"search_metadata": {
"max_id": 250126199840518145,
"since_id": 24012619984051000,
"refresh_url": "?since_id=250126199840518145&q=%23freebandnames&result_type=mixed&include_entities=1",
"next_results": "?max_id=249279667666817023&q=%23freebandnames&count=4&include_entities=1&result_type=mixed",
"count": 4,
"completed_in": 0.035,
"since_id_str": "24012619984051000",
"query": "%23freebandnames",
"max_id_str": "250126199840518145"
}
}

View file

@ -0,0 +1,190 @@
// +build use_ffjson
package benchmark
import (
"testing"
"github.com/pquerna/ffjson/ffjson"
)
func BenchmarkFF_Unmarshal_M(b *testing.B) {
b.SetBytes(int64(len(largeStructText)))
for i := 0; i < b.N; i++ {
var s LargeStruct
err := ffjson.UnmarshalFast(largeStructText, &s)
if err != nil {
b.Error(err)
}
}
}
func BenchmarkFF_Unmarshal_S(b *testing.B) {
for i := 0; i < b.N; i++ {
var s Entities
err := ffjson.UnmarshalFast(smallStructText, &s)
if err != nil {
b.Error(err)
}
}
b.SetBytes(int64(len(smallStructText)))
}
func BenchmarkFF_Marshal_M(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := ffjson.MarshalFast(&largeStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
b.SetBytes(l)
}
func BenchmarkFF_Marshal_S(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := ffjson.MarshalFast(&smallStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
b.SetBytes(l)
}
func BenchmarkFF_Marshal_M_Pool(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := ffjson.MarshalFast(&largeStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
ffjson.Pool(data)
}
b.SetBytes(l)
}
func BenchmarkFF_Marshal_L(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := ffjson.MarshalFast(&xlStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
b.SetBytes(l)
}
func BenchmarkFF_Marshal_L_Pool(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := ffjson.MarshalFast(&xlStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
ffjson.Pool(data)
}
b.SetBytes(l)
}
func BenchmarkFF_Marshal_L_Pool_Parallel(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := ffjson.MarshalFast(&xlStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
ffjson.Pool(data)
}
b.SetBytes(l)
}
func BenchmarkFF_Marshal_M_Pool_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
data, err := ffjson.MarshalFast(&largeStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
ffjson.Pool(data)
}
})
b.SetBytes(l)
}
func BenchmarkFF_Marshal_S_Pool(b *testing.B) {
var l int64
for i := 0; i < b.N; i++ {
data, err := ffjson.MarshalFast(&smallStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
ffjson.Pool(data)
}
b.SetBytes(l)
}
func BenchmarkFF_Marshal_S_Pool_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
data, err := ffjson.MarshalFast(&smallStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
ffjson.Pool(data)
}
})
b.SetBytes(l)
}
func BenchmarkFF_Marshal_S_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
data, err := ffjson.MarshalFast(&smallStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
})
b.SetBytes(l)
}
func BenchmarkFF_Marshal_M_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
data, err := ffjson.MarshalFast(&largeStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
})
b.SetBytes(l)
}
func BenchmarkFF_Marshal_L_Parallel(b *testing.B) {
var l int64
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
data, err := ffjson.MarshalFast(&xlStructData)
if err != nil {
b.Error(err)
}
l = int64(len(data))
}
})
b.SetBytes(l)
}

7
vendor/github.com/mailru/easyjson/benchmark/ujson.sh generated vendored Executable file
View file

@ -0,0 +1,7 @@
#/bin/bash
echo -n "Python ujson module, DECODE: "
python -m timeit -s "import ujson; data = open('`dirname $0`/example.json', 'r').read()" 'ujson.loads(data)'
echo -n "Python ujson module, ENCODE: "
python -m timeit -s "import ujson; data = open('`dirname $0`/example.json', 'r').read(); obj = ujson.loads(data)" 'ujson.dumps(obj)'

View file

@ -0,0 +1,184 @@
// Package bootstrap implements the bootstrapping logic: generation of a .go file to
// launch the actual generator and launching the generator itself.
//
// The package may be preferred to a command-line utility if generating the serializers
// from golang code is required.
package bootstrap
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"sort"
)
const genPackage = "github.com/mailru/easyjson/gen"
const pkgWriter = "github.com/mailru/easyjson/jwriter"
const pkgLexer = "github.com/mailru/easyjson/jlexer"
type Generator struct {
PkgPath, PkgName string
Types []string
NoStdMarshalers bool
SnakeCase bool
OmitEmpty bool
OutName string
BuildTags string
StubsOnly bool
LeaveTemps bool
NoFormat bool
}
// writeStub outputs an initial stubs for marshalers/unmarshalers so that the package
// using marshalers/unmarshales compiles correctly for boostrapping code.
func (g *Generator) writeStub() error {
f, err := os.Create(g.OutName)
if err != nil {
return err
}
defer f.Close()
if g.BuildTags != "" {
fmt.Fprintln(f, "// +build ", g.BuildTags)
fmt.Fprintln(f)
}
fmt.Fprintln(f, "// TEMPORARY AUTOGENERATED FILE: easyjson stub code to make the package")
fmt.Fprintln(f, "// compilable during generation.")
fmt.Fprintln(f)
fmt.Fprintln(f, "package ", g.PkgName)
if len(g.Types) > 0 {
fmt.Fprintln(f)
fmt.Fprintln(f, "import (")
fmt.Fprintln(f, ` "`+pkgWriter+`"`)
fmt.Fprintln(f, ` "`+pkgLexer+`"`)
fmt.Fprintln(f, ")")
}
sort.Strings(g.Types)
for _, t := range g.Types {
fmt.Fprintln(f)
if !g.NoStdMarshalers {
fmt.Fprintln(f, "func (", t, ") MarshalJSON() ([]byte, error) { return nil, nil }")
fmt.Fprintln(f, "func (*", t, ") UnmarshalJSON([]byte) error { return nil }")
}
fmt.Fprintln(f, "func (", t, ") MarshalEasyJSON(w *jwriter.Writer) {}")
fmt.Fprintln(f, "func (*", t, ") UnmarshalEasyJSON(l *jlexer.Lexer) {}")
fmt.Fprintln(f)
fmt.Fprintln(f, "type EasyJSON_exporter_"+t+" *"+t)
}
return nil
}
// writeMain creates a .go file that launches the generator if 'go run'.
func (g *Generator) writeMain() (path string, err error) {
f, err := ioutil.TempFile(filepath.Dir(g.OutName), "easyjson-bootstrap")
if err != nil {
return "", err
}
fmt.Fprintln(f, "// +build ignore")
fmt.Fprintln(f)
fmt.Fprintln(f, "// TEMPORARY AUTOGENERATED FILE: easyjson bootstapping code to launch")
fmt.Fprintln(f, "// the actual generator.")
fmt.Fprintln(f)
fmt.Fprintln(f, "package main")
fmt.Fprintln(f)
fmt.Fprintln(f, "import (")
fmt.Fprintln(f, ` "fmt"`)
fmt.Fprintln(f, ` "os"`)
fmt.Fprintln(f)
fmt.Fprintf(f, " %q\n", genPackage)
if len(g.Types) > 0 {
fmt.Fprintln(f)
fmt.Fprintf(f, " pkg %q\n", g.PkgPath)
}
fmt.Fprintln(f, ")")
fmt.Fprintln(f)
fmt.Fprintln(f, "func main() {")
fmt.Fprintf(f, " g := gen.NewGenerator(%q)\n", filepath.Base(g.OutName))
fmt.Fprintf(f, " g.SetPkg(%q, %q)\n", g.PkgName, g.PkgPath)
if g.BuildTags != "" {
fmt.Fprintf(f, " g.SetBuildTags(%q)\n", g.BuildTags)
}
if g.SnakeCase {
fmt.Fprintln(f, " g.UseSnakeCase()")
}
if g.OmitEmpty {
fmt.Fprintln(f, " g.OmitEmpty()")
}
if g.NoStdMarshalers {
fmt.Fprintln(f, " g.NoStdMarshalers()")
}
sort.Strings(g.Types)
for _, v := range g.Types {
fmt.Fprintln(f, " g.Add(pkg.EasyJSON_exporter_"+v+"(nil))")
}
fmt.Fprintln(f, " if err := g.Run(os.Stdout); err != nil {")
fmt.Fprintln(f, " fmt.Fprintln(os.Stderr, err)")
fmt.Fprintln(f, " os.Exit(1)")
fmt.Fprintln(f, " }")
fmt.Fprintln(f, "}")
src := f.Name()
if err := f.Close(); err != nil {
return src, err
}
dest := src + ".go"
return dest, os.Rename(src, dest)
}
func (g *Generator) Run() error {
if err := g.writeStub(); err != nil {
return err
}
if g.StubsOnly {
return nil
}
path, err := g.writeMain()
if err != nil {
return err
}
if !g.LeaveTemps {
defer os.Remove(path)
}
f, err := os.Create(g.OutName + ".tmp")
if err != nil {
return err
}
if !g.LeaveTemps {
defer os.Remove(f.Name()) // will not remove after rename
}
cmd := exec.Command("go", "run", "-tags", g.BuildTags, path)
cmd.Stdout = f
cmd.Stderr = os.Stderr
if err = cmd.Run(); err != nil {
return err
}
f.Close()
if !g.NoFormat {
cmd = exec.Command("gofmt", "-w", f.Name())
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
if err = cmd.Run(); err != nil {
return err
}
}
return os.Rename(f.Name(), g.OutName)
}

270
vendor/github.com/mailru/easyjson/buffer/pool.go generated vendored Normal file
View file

@ -0,0 +1,270 @@
// Package buffer implements a buffer for serialization, consisting of a chain of []byte-s to
// reduce copying and to allow reuse of individual chunks.
package buffer
import (
"io"
"sync"
)
// PoolConfig contains configuration for the allocation and reuse strategy.
type PoolConfig struct {
StartSize int // Minimum chunk size that is allocated.
PooledSize int // Minimum chunk size that is reused, reusing chunks too small will result in overhead.
MaxSize int // Maximum chunk size that will be allocated.
}
var config = PoolConfig{
StartSize: 128,
PooledSize: 512,
MaxSize: 32768,
}
// Reuse pool: chunk size -> pool.
var buffers = map[int]*sync.Pool{}
func initBuffers() {
for l := config.PooledSize; l <= config.MaxSize; l *= 2 {
buffers[l] = new(sync.Pool)
}
}
func init() {
initBuffers()
}
// Init sets up a non-default pooling and allocation strategy. Should be run before serialization is done.
func Init(cfg PoolConfig) {
config = cfg
initBuffers()
}
// putBuf puts a chunk to reuse pool if it can be reused.
func putBuf(buf []byte) {
size := cap(buf)
if size < config.PooledSize {
return
}
if c := buffers[size]; c != nil {
c.Put(buf[:0])
}
}
// getBuf gets a chunk from reuse pool or creates a new one if reuse failed.
func getBuf(size int) []byte {
if size < config.PooledSize {
return make([]byte, 0, size)
}
if c := buffers[size]; c != nil {
v := c.Get()
if v != nil {
return v.([]byte)
}
}
return make([]byte, 0, size)
}
// Buffer is a buffer optimized for serialization without extra copying.
type Buffer struct {
// Buf is the current chunk that can be used for serialization.
Buf []byte
toPool []byte
bufs [][]byte
}
// EnsureSpace makes sure that the current chunk contains at least s free bytes,
// possibly creating a new chunk.
func (b *Buffer) EnsureSpace(s int) {
if cap(b.Buf)-len(b.Buf) >= s {
return
}
l := len(b.Buf)
if l > 0 {
if cap(b.toPool) != cap(b.Buf) {
// Chunk was reallocated, toPool can be pooled.
putBuf(b.toPool)
}
if cap(b.bufs) == 0 {
b.bufs = make([][]byte, 0, 8)
}
b.bufs = append(b.bufs, b.Buf)
l = cap(b.toPool) * 2
} else {
l = config.StartSize
}
if l > config.MaxSize {
l = config.MaxSize
}
b.Buf = getBuf(l)
b.toPool = b.Buf
}
// AppendByte appends a single byte to buffer.
func (b *Buffer) AppendByte(data byte) {
if cap(b.Buf) == len(b.Buf) { // EnsureSpace won't be inlined.
b.EnsureSpace(1)
}
b.Buf = append(b.Buf, data)
}
// AppendBytes appends a byte slice to buffer.
func (b *Buffer) AppendBytes(data []byte) {
for len(data) > 0 {
if cap(b.Buf) == len(b.Buf) { // EnsureSpace won't be inlined.
b.EnsureSpace(1)
}
sz := cap(b.Buf) - len(b.Buf)
if sz > len(data) {
sz = len(data)
}
b.Buf = append(b.Buf, data[:sz]...)
data = data[sz:]
}
}
// AppendBytes appends a string to buffer.
func (b *Buffer) AppendString(data string) {
for len(data) > 0 {
if cap(b.Buf) == len(b.Buf) { // EnsureSpace won't be inlined.
b.EnsureSpace(1)
}
sz := cap(b.Buf) - len(b.Buf)
if sz > len(data) {
sz = len(data)
}
b.Buf = append(b.Buf, data[:sz]...)
data = data[sz:]
}
}
// Size computes the size of a buffer by adding sizes of every chunk.
func (b *Buffer) Size() int {
size := len(b.Buf)
for _, buf := range b.bufs {
size += len(buf)
}
return size
}
// DumpTo outputs the contents of a buffer to a writer and resets the buffer.
func (b *Buffer) DumpTo(w io.Writer) (written int, err error) {
var n int
for _, buf := range b.bufs {
if err == nil {
n, err = w.Write(buf)
written += n
}
putBuf(buf)
}
if err == nil {
n, err = w.Write(b.Buf)
written += n
}
putBuf(b.toPool)
b.bufs = nil
b.Buf = nil
b.toPool = nil
return
}
// BuildBytes creates a single byte slice with all the contents of the buffer. Data is
// copied if it does not fit in a single chunk. You can optionally provide one byte
// slice as argument that it will try to reuse.
func (b *Buffer) BuildBytes(reuse ...[]byte) []byte {
if len(b.bufs) == 0 {
ret := b.Buf
b.toPool = nil
b.Buf = nil
return ret
}
var ret []byte
size := b.Size()
// If we got a buffer as argument and it is big enought, reuse it.
if len(reuse) == 1 && cap(reuse[0]) >= size {
ret = reuse[0][:0]
} else {
ret = make([]byte, 0, size)
}
for _, buf := range b.bufs {
ret = append(ret, buf...)
putBuf(buf)
}
ret = append(ret, b.Buf...)
putBuf(b.toPool)
b.bufs = nil
b.toPool = nil
b.Buf = nil
return ret
}
type readCloser struct {
offset int
bufs [][]byte
}
func (r *readCloser) Read(p []byte) (n int, err error) {
for _, buf := range r.bufs {
// Copy as much as we can.
x := copy(p[n:], buf[r.offset:])
n += x // Increment how much we filled.
// Did we empty the whole buffer?
if r.offset+x == len(buf) {
// On to the next buffer.
r.offset = 0
r.bufs = r.bufs[1:]
// We can release this buffer.
putBuf(buf)
} else {
r.offset += x
}
if n == len(p) {
break
}
}
// No buffers left or nothing read?
if len(r.bufs) == 0 {
err = io.EOF
}
return
}
func (r *readCloser) Close() error {
// Release all remaining buffers.
for _, buf := range r.bufs {
putBuf(buf)
}
// In case Close gets called multiple times.
r.bufs = nil
return nil
}
// ReadCloser creates an io.ReadCloser with all the contents of the buffer.
func (b *Buffer) ReadCloser() io.ReadCloser {
ret := &readCloser{0, append(b.bufs, b.Buf)}
b.bufs = nil
b.toPool = nil
b.Buf = nil
return ret
}

107
vendor/github.com/mailru/easyjson/buffer/pool_test.go generated vendored Normal file
View file

@ -0,0 +1,107 @@
package buffer
import (
"bytes"
"testing"
)
func TestAppendByte(t *testing.T) {
var b Buffer
var want []byte
for i := 0; i < 1000; i++ {
b.AppendByte(1)
b.AppendByte(2)
want = append(want, 1, 2)
}
got := b.BuildBytes()
if !bytes.Equal(got, want) {
t.Errorf("BuildBytes() = %v; want %v", got, want)
}
}
func TestAppendBytes(t *testing.T) {
var b Buffer
var want []byte
for i := 0; i < 1000; i++ {
b.AppendBytes([]byte{1, 2})
want = append(want, 1, 2)
}
got := b.BuildBytes()
if !bytes.Equal(got, want) {
t.Errorf("BuildBytes() = %v; want %v", got, want)
}
}
func TestAppendString(t *testing.T) {
var b Buffer
var want []byte
s := "test"
for i := 0; i < 1000; i++ {
b.AppendBytes([]byte(s))
want = append(want, s...)
}
got := b.BuildBytes()
if !bytes.Equal(got, want) {
t.Errorf("BuildBytes() = %v; want %v", got, want)
}
}
func TestDumpTo(t *testing.T) {
var b Buffer
var want []byte
s := "test"
for i := 0; i < 1000; i++ {
b.AppendBytes([]byte(s))
want = append(want, s...)
}
out := &bytes.Buffer{}
n, err := b.DumpTo(out)
if err != nil {
t.Errorf("DumpTo() error: %v", err)
}
got := out.Bytes()
if !bytes.Equal(got, want) {
t.Errorf("DumpTo(): got %v; want %v", got, want)
}
if n != len(want) {
t.Errorf("DumpTo() = %v; want %v", n, len(want))
}
}
func TestReadCloser(t *testing.T) {
var b Buffer
var want []byte
s := "test"
for i := 0; i < 1000; i++ {
b.AppendBytes([]byte(s))
want = append(want, s...)
}
out := &bytes.Buffer{}
rc := b.ReadCloser()
n, err := out.ReadFrom(rc)
if err != nil {
t.Errorf("ReadCloser() error: %v", err)
}
rc.Close() // Will always return nil
got := out.Bytes()
if !bytes.Equal(got, want) {
t.Errorf("DumpTo(): got %v; want %v", got, want)
}
if n != int64(len(want)) {
t.Errorf("DumpTo() = %v; want %v", n, len(want))
}
}

99
vendor/github.com/mailru/easyjson/easyjson/main.go generated vendored Normal file
View file

@ -0,0 +1,99 @@
package main
import (
"errors"
"flag"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/mailru/easyjson/bootstrap"
// Reference the gen package to be friendly to vendoring tools,
// as it is an indirect dependency.
// (The temporary bootstrapping code uses it.)
_ "github.com/mailru/easyjson/gen"
"github.com/mailru/easyjson/parser"
)
var buildTags = flag.String("build_tags", "", "build tags to add to generated file")
var snakeCase = flag.Bool("snake_case", false, "use snake_case names instead of CamelCase by default")
var noStdMarshalers = flag.Bool("no_std_marshalers", false, "don't generate MarshalJSON/UnmarshalJSON funcs")
var omitEmpty = flag.Bool("omit_empty", false, "omit empty fields by default")
var allStructs = flag.Bool("all", false, "generate marshaler/unmarshalers for all structs in a file")
var leaveTemps = flag.Bool("leave_temps", false, "do not delete temporary files")
var stubs = flag.Bool("stubs", false, "only generate stubs for marshaler/unmarshaler funcs")
var noformat = flag.Bool("noformat", false, "do not run 'gofmt -w' on output file")
var specifiedName = flag.String("output_filename", "", "specify the filename of the output")
var processPkg = flag.Bool("pkg", false, "process the whole package instead of just the given file")
func generate(fname string) (err error) {
fInfo, err := os.Stat(fname)
if err != nil {
return err
}
p := parser.Parser{AllStructs: *allStructs}
if err := p.Parse(fname, fInfo.IsDir()); err != nil {
return fmt.Errorf("Error parsing %v: %v", fname, err)
}
var outName string
if fInfo.IsDir() {
outName = filepath.Join(fname, p.PkgName+"_easyjson.go")
} else {
if s := strings.TrimSuffix(fname, ".go"); s == fname {
return errors.New("Filename must end in '.go'")
} else {
outName = s + "_easyjson.go"
}
}
if *specifiedName != "" {
outName = *specifiedName
}
g := bootstrap.Generator{
BuildTags: *buildTags,
PkgPath: p.PkgPath,
PkgName: p.PkgName,
Types: p.StructNames,
SnakeCase: *snakeCase,
NoStdMarshalers: *noStdMarshalers,
OmitEmpty: *omitEmpty,
LeaveTemps: *leaveTemps,
OutName: outName,
StubsOnly: *stubs,
NoFormat: *noformat,
}
if err := g.Run(); err != nil {
return fmt.Errorf("Bootstrap failed: %v", err)
}
return nil
}
func main() {
flag.Parse()
files := flag.Args()
gofile := os.Getenv("GOFILE")
if *processPkg {
gofile = filepath.Dir(gofile)
}
if len(files) == 0 && gofile != "" {
files = []string{gofile}
} else if len(files) == 0 {
flag.Usage()
os.Exit(1)
}
for _, fname := range files {
if err := generate(fname); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
}

471
vendor/github.com/mailru/easyjson/gen/decoder.go generated vendored Normal file
View file

@ -0,0 +1,471 @@
package gen
import (
"encoding"
"encoding/json"
"fmt"
"reflect"
"strings"
"unicode"
"github.com/mailru/easyjson"
)
// Target this byte size for initial slice allocation to reduce garbage collection.
const minSliceBytes = 64
func (g *Generator) getDecoderName(t reflect.Type) string {
return g.functionName("decode", t)
}
var primitiveDecoders = map[reflect.Kind]string{
reflect.String: "in.String()",
reflect.Bool: "in.Bool()",
reflect.Int: "in.Int()",
reflect.Int8: "in.Int8()",
reflect.Int16: "in.Int16()",
reflect.Int32: "in.Int32()",
reflect.Int64: "in.Int64()",
reflect.Uint: "in.Uint()",
reflect.Uint8: "in.Uint8()",
reflect.Uint16: "in.Uint16()",
reflect.Uint32: "in.Uint32()",
reflect.Uint64: "in.Uint64()",
reflect.Float32: "in.Float32()",
reflect.Float64: "in.Float64()",
}
var primitiveStringDecoders = map[reflect.Kind]string{
reflect.Int: "in.IntStr()",
reflect.Int8: "in.Int8Str()",
reflect.Int16: "in.Int16Str()",
reflect.Int32: "in.Int32Str()",
reflect.Int64: "in.Int64Str()",
reflect.Uint: "in.UintStr()",
reflect.Uint8: "in.Uint8Str()",
reflect.Uint16: "in.Uint16Str()",
reflect.Uint32: "in.Uint32Str()",
reflect.Uint64: "in.Uint64Str()",
}
// genTypeDecoder generates decoding code for the type t, but uses unmarshaler interface if implemented by t.
func (g *Generator) genTypeDecoder(t reflect.Type, out string, tags fieldTags, indent int) error {
ws := strings.Repeat(" ", indent)
unmarshalerIface := reflect.TypeOf((*easyjson.Unmarshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(unmarshalerIface) {
fmt.Fprintln(g.out, ws+"("+out+").UnmarshalEasyJSON(in)")
return nil
}
unmarshalerIface = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(unmarshalerIface) {
fmt.Fprintln(g.out, ws+"if data := in.Raw(); in.Ok() {")
fmt.Fprintln(g.out, ws+" in.AddError( ("+out+").UnmarshalJSON(data) )")
fmt.Fprintln(g.out, ws+"}")
return nil
}
unmarshalerIface = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(unmarshalerIface) {
fmt.Fprintln(g.out, ws+"if data := in.UnsafeBytes(); in.Ok() {")
fmt.Fprintln(g.out, ws+" in.AddError( ("+out+").UnmarshalText(data) )")
fmt.Fprintln(g.out, ws+"}")
return nil
}
err := g.genTypeDecoderNoCheck(t, out, tags, indent)
return err
}
// genTypeDecoderNoCheck generates decoding code for the type t.
func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags fieldTags, indent int) error {
ws := strings.Repeat(" ", indent)
// Check whether type is primitive, needs to be done after interface check.
if dec := primitiveStringDecoders[t.Kind()]; dec != "" && tags.asString {
fmt.Fprintln(g.out, ws+out+" = "+g.getType(t)+"("+dec+")")
return nil
} else if dec := primitiveDecoders[t.Kind()]; dec != "" {
fmt.Fprintln(g.out, ws+out+" = "+g.getType(t)+"("+dec+")")
return nil
}
switch t.Kind() {
case reflect.Slice:
tmpVar := g.uniqueVarName()
elem := t.Elem()
if elem.Kind() == reflect.Uint8 {
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+" "+out+" = nil")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" "+out+" = in.Bytes()")
fmt.Fprintln(g.out, ws+"}")
} else {
capacity := minSliceBytes / elem.Size()
if capacity == 0 {
capacity = 1
}
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+" "+out+" = nil")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" in.Delim('[')")
fmt.Fprintln(g.out, ws+" if "+out+" == nil {")
fmt.Fprintln(g.out, ws+" if !in.IsDelim(']') {")
fmt.Fprintln(g.out, ws+" "+out+" = make("+g.getType(t)+", 0, "+fmt.Sprint(capacity)+")")
fmt.Fprintln(g.out, ws+" } else {")
fmt.Fprintln(g.out, ws+" "+out+" = "+g.getType(t)+"{}")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" } else { ")
fmt.Fprintln(g.out, ws+" "+out+" = ("+out+")[:0]")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" for !in.IsDelim(']') {")
fmt.Fprintln(g.out, ws+" var "+tmpVar+" "+g.getType(elem))
g.genTypeDecoder(elem, tmpVar, tags, indent+2)
fmt.Fprintln(g.out, ws+" "+out+" = append("+out+", "+tmpVar+")")
fmt.Fprintln(g.out, ws+" in.WantComma()")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" in.Delim(']')")
fmt.Fprintln(g.out, ws+"}")
}
case reflect.Array:
iterVar := g.uniqueVarName()
elem := t.Elem()
if elem.Kind() == reflect.Uint8 {
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" copy("+out+"[:], in.Bytes())")
fmt.Fprintln(g.out, ws+"}")
} else {
length := t.Len()
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" in.Delim('[')")
fmt.Fprintln(g.out, ws+" "+iterVar+" := 0")
fmt.Fprintln(g.out, ws+" for !in.IsDelim(']') {")
fmt.Fprintln(g.out, ws+" if "+iterVar+" < "+fmt.Sprint(length)+" {")
g.genTypeDecoder(elem, out+"["+iterVar+"]", tags, indent+3)
fmt.Fprintln(g.out, ws+" "+iterVar+"++")
fmt.Fprintln(g.out, ws+" } else {")
fmt.Fprintln(g.out, ws+" in.SkipRecursive()")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" in.WantComma()")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" in.Delim(']')")
fmt.Fprintln(g.out, ws+"}")
}
case reflect.Struct:
dec := g.getDecoderName(t)
g.addType(t)
fmt.Fprintln(g.out, ws+dec+"(in, &"+out+")")
case reflect.Ptr:
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+" "+out+" = nil")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" if "+out+" == nil {")
fmt.Fprintln(g.out, ws+" "+out+" = new("+g.getType(t.Elem())+")")
fmt.Fprintln(g.out, ws+" }")
g.genTypeDecoder(t.Elem(), "*"+out, tags, indent+1)
fmt.Fprintln(g.out, ws+"}")
case reflect.Map:
key := t.Key()
if key.Kind() != reflect.String {
return fmt.Errorf("map type %v not supported: only string keys are allowed", key)
}
elem := t.Elem()
tmpVar := g.uniqueVarName()
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" in.Delim('{')")
fmt.Fprintln(g.out, ws+" if !in.IsDelim('}') {")
fmt.Fprintln(g.out, ws+" "+out+" = make("+g.getType(t)+")")
fmt.Fprintln(g.out, ws+" } else {")
fmt.Fprintln(g.out, ws+" "+out+" = nil")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" for !in.IsDelim('}') {")
fmt.Fprintln(g.out, ws+" key := "+g.getType(t.Key())+"(in.String())")
fmt.Fprintln(g.out, ws+" in.WantColon()")
fmt.Fprintln(g.out, ws+" var "+tmpVar+" "+g.getType(elem))
g.genTypeDecoder(elem, tmpVar, tags, indent+2)
fmt.Fprintln(g.out, ws+" ("+out+")[key] = "+tmpVar)
fmt.Fprintln(g.out, ws+" in.WantComma()")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" in.Delim('}')")
fmt.Fprintln(g.out, ws+"}")
case reflect.Interface:
if t.NumMethod() != 0 {
return fmt.Errorf("interface type %v not supported: only interface{} is allowed", t)
}
fmt.Fprintln(g.out, ws+"if m, ok := "+out+".(easyjson.Unmarshaler); ok {")
fmt.Fprintln(g.out, ws+"m.UnmarshalEasyJSON(in)")
fmt.Fprintln(g.out, ws+"} else if m, ok := "+out+".(json.Unmarshaler); ok {")
fmt.Fprintln(g.out, ws+"m.UnmarshalJSON(in.Raw())")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" "+out+" = in.Interface()")
fmt.Fprintln(g.out, ws+"}")
default:
return fmt.Errorf("don't know how to decode %v", t)
}
return nil
}
func (g *Generator) genStructFieldDecoder(t reflect.Type, f reflect.StructField) error {
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
tags := parseFieldTags(f)
if tags.omit {
return nil
}
fmt.Fprintf(g.out, " case %q:\n", jsonName)
if err := g.genTypeDecoder(f.Type, "out."+f.Name, tags, 3); err != nil {
return err
}
if tags.required {
fmt.Fprintf(g.out, "%sSet = true\n", f.Name)
}
return nil
}
func (g *Generator) genRequiredFieldSet(t reflect.Type, f reflect.StructField) {
tags := parseFieldTags(f)
if !tags.required {
return
}
fmt.Fprintf(g.out, "var %sSet bool\n", f.Name)
}
func (g *Generator) genRequiredFieldCheck(t reflect.Type, f reflect.StructField) {
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
tags := parseFieldTags(f)
if !tags.required {
return
}
g.imports["fmt"] = "fmt"
fmt.Fprintf(g.out, "if !%sSet {\n", f.Name)
fmt.Fprintf(g.out, " in.AddError(fmt.Errorf(\"key '%s' is required\"))\n", jsonName)
fmt.Fprintf(g.out, "}\n")
}
func mergeStructFields(fields1, fields2 []reflect.StructField) (fields []reflect.StructField) {
used := map[string]bool{}
for _, f := range fields2 {
used[f.Name] = true
fields = append(fields, f)
}
for _, f := range fields1 {
if !used[f.Name] {
fields = append(fields, f)
}
}
return
}
func getStructFields(t reflect.Type) ([]reflect.StructField, error) {
if t.Kind() != reflect.Struct {
return nil, fmt.Errorf("got %v; expected a struct", t)
}
var efields []reflect.StructField
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if !f.Anonymous {
continue
}
t1 := f.Type
if t1.Kind() == reflect.Ptr {
t1 = t1.Elem()
}
fs, err := getStructFields(t1)
if err != nil {
return nil, fmt.Errorf("error processing embedded field: %v", err)
}
efields = mergeStructFields(efields, fs)
}
var fields []reflect.StructField
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if f.Anonymous {
continue
}
c := []rune(f.Name)[0]
if unicode.IsUpper(c) {
fields = append(fields, f)
}
}
return mergeStructFields(efields, fields), nil
}
func (g *Generator) genDecoder(t reflect.Type) error {
switch t.Kind() {
case reflect.Slice, reflect.Array, reflect.Map:
return g.genSliceArrayDecoder(t)
default:
return g.genStructDecoder(t)
}
}
func (g *Generator) genSliceArrayDecoder(t reflect.Type) error {
switch t.Kind() {
case reflect.Slice, reflect.Array, reflect.Map:
default:
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice/array/map type", t)
}
fname := g.getDecoderName(t)
typ := g.getType(t)
fmt.Fprintln(g.out, "func "+fname+"(in *jlexer.Lexer, out *"+typ+") {")
fmt.Fprintln(g.out, " isTopLevel := in.IsStart()")
err := g.genTypeDecoderNoCheck(t, "*out", fieldTags{}, 1)
if err != nil {
return err
}
fmt.Fprintln(g.out, " if isTopLevel {")
fmt.Fprintln(g.out, " in.Consumed()")
fmt.Fprintln(g.out, " }")
fmt.Fprintln(g.out, "}")
return nil
}
func (g *Generator) genStructDecoder(t reflect.Type) error {
if t.Kind() != reflect.Struct {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct type", t)
}
fname := g.getDecoderName(t)
typ := g.getType(t)
fmt.Fprintln(g.out, "func "+fname+"(in *jlexer.Lexer, out *"+typ+") {")
fmt.Fprintln(g.out, " isTopLevel := in.IsStart()")
fmt.Fprintln(g.out, " if in.IsNull() {")
fmt.Fprintln(g.out, " if isTopLevel {")
fmt.Fprintln(g.out, " in.Consumed()")
fmt.Fprintln(g.out, " }")
fmt.Fprintln(g.out, " in.Skip()")
fmt.Fprintln(g.out, " return")
fmt.Fprintln(g.out, " }")
// Init embedded pointer fields.
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if !f.Anonymous || f.Type.Kind() != reflect.Ptr {
continue
}
fmt.Fprintln(g.out, " out."+f.Name+" = new("+g.getType(f.Type.Elem())+")")
}
fs, err := getStructFields(t)
if err != nil {
return fmt.Errorf("cannot generate decoder for %v: %v", t, err)
}
for _, f := range fs {
g.genRequiredFieldSet(t, f)
}
fmt.Fprintln(g.out, " in.Delim('{')")
fmt.Fprintln(g.out, " for !in.IsDelim('}') {")
fmt.Fprintln(g.out, " key := in.UnsafeString()")
fmt.Fprintln(g.out, " in.WantColon()")
fmt.Fprintln(g.out, " if in.IsNull() {")
fmt.Fprintln(g.out, " in.Skip()")
fmt.Fprintln(g.out, " in.WantComma()")
fmt.Fprintln(g.out, " continue")
fmt.Fprintln(g.out, " }")
fmt.Fprintln(g.out, " switch key {")
for _, f := range fs {
if err := g.genStructFieldDecoder(t, f); err != nil {
return err
}
}
fmt.Fprintln(g.out, " default:")
fmt.Fprintln(g.out, " in.SkipRecursive()")
fmt.Fprintln(g.out, " }")
fmt.Fprintln(g.out, " in.WantComma()")
fmt.Fprintln(g.out, " }")
fmt.Fprintln(g.out, " in.Delim('}')")
fmt.Fprintln(g.out, " if isTopLevel {")
fmt.Fprintln(g.out, " in.Consumed()")
fmt.Fprintln(g.out, " }")
for _, f := range fs {
g.genRequiredFieldCheck(t, f)
}
fmt.Fprintln(g.out, "}")
return nil
}
func (g *Generator) genStructUnmarshaler(t reflect.Type) error {
switch t.Kind() {
case reflect.Slice, reflect.Array, reflect.Map, reflect.Struct:
default:
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice/array/map type", t)
}
fname := g.getDecoderName(t)
typ := g.getType(t)
if !g.noStdMarshalers {
fmt.Fprintln(g.out, "// UnmarshalJSON supports json.Unmarshaler interface")
fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalJSON(data []byte) error {")
fmt.Fprintln(g.out, " r := jlexer.Lexer{Data: data}")
fmt.Fprintln(g.out, " "+fname+"(&r, v)")
fmt.Fprintln(g.out, " return r.Error()")
fmt.Fprintln(g.out, "}")
}
fmt.Fprintln(g.out, "// UnmarshalEasyJSON supports easyjson.Unmarshaler interface")
fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalEasyJSON(l *jlexer.Lexer) {")
fmt.Fprintln(g.out, " "+fname+"(l, v)")
fmt.Fprintln(g.out, "}")
return nil
}

358
vendor/github.com/mailru/easyjson/gen/encoder.go generated vendored Normal file
View file

@ -0,0 +1,358 @@
package gen
import (
"encoding"
"encoding/json"
"fmt"
"reflect"
"strconv"
"strings"
"github.com/mailru/easyjson"
)
func (g *Generator) getEncoderName(t reflect.Type) string {
return g.functionName("encode", t)
}
var primitiveEncoders = map[reflect.Kind]string{
reflect.String: "out.String(string(%v))",
reflect.Bool: "out.Bool(bool(%v))",
reflect.Int: "out.Int(int(%v))",
reflect.Int8: "out.Int8(int8(%v))",
reflect.Int16: "out.Int16(int16(%v))",
reflect.Int32: "out.Int32(int32(%v))",
reflect.Int64: "out.Int64(int64(%v))",
reflect.Uint: "out.Uint(uint(%v))",
reflect.Uint8: "out.Uint8(uint8(%v))",
reflect.Uint16: "out.Uint16(uint16(%v))",
reflect.Uint32: "out.Uint32(uint32(%v))",
reflect.Uint64: "out.Uint64(uint64(%v))",
reflect.Float32: "out.Float32(float32(%v))",
reflect.Float64: "out.Float64(float64(%v))",
}
var primitiveStringEncoders = map[reflect.Kind]string{
reflect.Int: "out.IntStr(int(%v))",
reflect.Int8: "out.Int8Str(int8(%v))",
reflect.Int16: "out.Int16Str(int16(%v))",
reflect.Int32: "out.Int32Str(int32(%v))",
reflect.Int64: "out.Int64Str(int64(%v))",
reflect.Uint: "out.UintStr(uint(%v))",
reflect.Uint8: "out.Uint8Str(uint8(%v))",
reflect.Uint16: "out.Uint16Str(uint16(%v))",
reflect.Uint32: "out.Uint32Str(uint32(%v))",
reflect.Uint64: "out.Uint64Str(uint64(%v))",
}
// fieldTags contains parsed version of json struct field tags.
type fieldTags struct {
name string
omit bool
omitEmpty bool
noOmitEmpty bool
asString bool
required bool
}
// parseFieldTags parses the json field tag into a structure.
func parseFieldTags(f reflect.StructField) fieldTags {
var ret fieldTags
for i, s := range strings.Split(f.Tag.Get("json"), ",") {
switch {
case i == 0 && s == "-":
ret.omit = true
case i == 0:
ret.name = s
case s == "omitempty":
ret.omitEmpty = true
case s == "!omitempty":
ret.noOmitEmpty = true
case s == "string":
ret.asString = true
case s == "required":
ret.required = true
}
}
return ret
}
// genTypeEncoder generates code that encodes in of type t into the writer, but uses marshaler interface if implemented by t.
func (g *Generator) genTypeEncoder(t reflect.Type, in string, tags fieldTags, indent int) error {
ws := strings.Repeat(" ", indent)
marshalerIface := reflect.TypeOf((*easyjson.Marshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(marshalerIface) {
fmt.Fprintln(g.out, ws+"("+in+").MarshalEasyJSON(out)")
return nil
}
marshalerIface = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(marshalerIface) {
fmt.Fprintln(g.out, ws+"out.Raw( ("+in+").MarshalJSON() )")
return nil
}
marshalerIface = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(marshalerIface) {
fmt.Fprintln(g.out, ws+"out.RawText( ("+in+").MarshalText() )")
return nil
}
err := g.genTypeEncoderNoCheck(t, in, tags, indent)
return err
}
// genTypeEncoderNoCheck generates code that encodes in of type t into the writer.
func (g *Generator) genTypeEncoderNoCheck(t reflect.Type, in string, tags fieldTags, indent int) error {
ws := strings.Repeat(" ", indent)
// Check whether type is primitive, needs to be done after interface check.
if enc := primitiveStringEncoders[t.Kind()]; enc != "" && tags.asString {
fmt.Fprintf(g.out, ws+enc+"\n", in)
return nil
} else if enc := primitiveEncoders[t.Kind()]; enc != "" {
fmt.Fprintf(g.out, ws+enc+"\n", in)
return nil
}
switch t.Kind() {
case reflect.Slice:
elem := t.Elem()
iVar := g.uniqueVarName()
vVar := g.uniqueVarName()
if t.Elem().Kind() == reflect.Uint8 {
fmt.Fprintln(g.out, ws+"out.Base64Bytes("+in+")")
} else {
fmt.Fprintln(g.out, ws+"if "+in+" == nil && (out.Flags & jwriter.NilSliceAsEmpty) == 0 {")
fmt.Fprintln(g.out, ws+` out.RawString("null")`)
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" out.RawByte('[')")
fmt.Fprintln(g.out, ws+" for "+iVar+", "+vVar+" := range "+in+" {")
fmt.Fprintln(g.out, ws+" if "+iVar+" > 0 {")
fmt.Fprintln(g.out, ws+" out.RawByte(',')")
fmt.Fprintln(g.out, ws+" }")
g.genTypeEncoder(elem, vVar, tags, indent+2)
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" out.RawByte(']')")
fmt.Fprintln(g.out, ws+"}")
}
case reflect.Array:
elem := t.Elem()
iVar := g.uniqueVarName()
if t.Elem().Kind() == reflect.Uint8 {
fmt.Fprintln(g.out, ws+"out.Base64Bytes("+in+"[:])")
} else {
fmt.Fprintln(g.out, ws+"out.RawByte('[')")
fmt.Fprintln(g.out, ws+"for "+iVar+" := range "+in+" {")
fmt.Fprintln(g.out, ws+" if "+iVar+" > 0 {")
fmt.Fprintln(g.out, ws+" out.RawByte(',')")
fmt.Fprintln(g.out, ws+" }")
g.genTypeEncoder(elem, in+"["+iVar+"]", tags, indent+1)
fmt.Fprintln(g.out, ws+"}")
fmt.Fprintln(g.out, ws+"out.RawByte(']')")
}
case reflect.Struct:
enc := g.getEncoderName(t)
g.addType(t)
fmt.Fprintln(g.out, ws+enc+"(out, "+in+")")
case reflect.Ptr:
fmt.Fprintln(g.out, ws+"if "+in+" == nil {")
fmt.Fprintln(g.out, ws+` out.RawString("null")`)
fmt.Fprintln(g.out, ws+"} else {")
g.genTypeEncoder(t.Elem(), "*"+in, tags, indent+1)
fmt.Fprintln(g.out, ws+"}")
case reflect.Map:
key := t.Key()
if key.Kind() != reflect.String {
return fmt.Errorf("map type %v not supported: only string keys are allowed", key)
}
tmpVar := g.uniqueVarName()
fmt.Fprintln(g.out, ws+"if "+in+" == nil && (out.Flags & jwriter.NilMapAsEmpty) == 0 {")
fmt.Fprintln(g.out, ws+" out.RawString(`null`)")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" out.RawByte('{')")
fmt.Fprintln(g.out, ws+" "+tmpVar+"First := true")
fmt.Fprintln(g.out, ws+" for "+tmpVar+"Name, "+tmpVar+"Value := range "+in+" {")
fmt.Fprintln(g.out, ws+" if !"+tmpVar+"First { out.RawByte(',') }")
fmt.Fprintln(g.out, ws+" "+tmpVar+"First = false")
fmt.Fprintln(g.out, ws+" out.String(string("+tmpVar+"Name))")
fmt.Fprintln(g.out, ws+" out.RawByte(':')")
g.genTypeEncoder(t.Elem(), tmpVar+"Value", tags, indent+2)
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" out.RawByte('}')")
fmt.Fprintln(g.out, ws+"}")
case reflect.Interface:
if t.NumMethod() != 0 {
return fmt.Errorf("interface type %v not supported: only interface{} is allowed", t)
}
fmt.Fprintln(g.out, ws+"if m, ok := "+in+".(easyjson.Marshaler); ok {")
fmt.Fprintln(g.out, ws+" m.MarshalEasyJSON(out)")
fmt.Fprintln(g.out, ws+"} else if m, ok := "+in+".(json.Marshaler); ok {")
fmt.Fprintln(g.out, ws+" out.Raw(m.MarshalJSON())")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" out.Raw(json.Marshal("+in+"))")
fmt.Fprintln(g.out, ws+"}")
default:
return fmt.Errorf("don't know how to encode %v", t)
}
return nil
}
func (g *Generator) notEmptyCheck(t reflect.Type, v string) string {
optionalIface := reflect.TypeOf((*easyjson.Optional)(nil)).Elem()
if reflect.PtrTo(t).Implements(optionalIface) {
return "(" + v + ").IsDefined()"
}
switch t.Kind() {
case reflect.Slice, reflect.Map:
return "len(" + v + ") != 0"
case reflect.Interface, reflect.Ptr:
return v + " != nil"
case reflect.Bool:
return v
case reflect.String:
return v + ` != ""`
case reflect.Float32, reflect.Float64,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return v + " != 0"
default:
// note: Array types don't have a useful empty value
return "true"
}
}
func (g *Generator) genStructFieldEncoder(t reflect.Type, f reflect.StructField) error {
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
tags := parseFieldTags(f)
if tags.omit {
return nil
}
if !tags.omitEmpty && !g.omitEmpty || tags.noOmitEmpty {
fmt.Fprintln(g.out, " if !first { out.RawByte(',') }")
fmt.Fprintln(g.out, " first = false")
fmt.Fprintf(g.out, " out.RawString(%q)\n", strconv.Quote(jsonName)+":")
return g.genTypeEncoder(f.Type, "in."+f.Name, tags, 1)
}
fmt.Fprintln(g.out, " if", g.notEmptyCheck(f.Type, "in."+f.Name), "{")
fmt.Fprintln(g.out, " if !first { out.RawByte(',') }")
fmt.Fprintln(g.out, " first = false")
fmt.Fprintf(g.out, " out.RawString(%q)\n", strconv.Quote(jsonName)+":")
if err := g.genTypeEncoder(f.Type, "in."+f.Name, tags, 2); err != nil {
return err
}
fmt.Fprintln(g.out, " }")
return nil
}
func (g *Generator) genEncoder(t reflect.Type) error {
switch t.Kind() {
case reflect.Slice, reflect.Array, reflect.Map:
return g.genSliceArrayMapEncoder(t)
default:
return g.genStructEncoder(t)
}
}
func (g *Generator) genSliceArrayMapEncoder(t reflect.Type) error {
switch t.Kind() {
case reflect.Slice, reflect.Array, reflect.Map:
default:
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice/array/map type", t)
}
fname := g.getEncoderName(t)
typ := g.getType(t)
fmt.Fprintln(g.out, "func "+fname+"(out *jwriter.Writer, in "+typ+") {")
err := g.genTypeEncoderNoCheck(t, "in", fieldTags{}, 1)
if err != nil {
return err
}
fmt.Fprintln(g.out, "}")
return nil
}
func (g *Generator) genStructEncoder(t reflect.Type) error {
if t.Kind() != reflect.Struct {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct type", t)
}
fname := g.getEncoderName(t)
typ := g.getType(t)
fmt.Fprintln(g.out, "func "+fname+"(out *jwriter.Writer, in "+typ+") {")
fmt.Fprintln(g.out, " out.RawByte('{')")
fmt.Fprintln(g.out, " first := true")
fmt.Fprintln(g.out, " _ = first")
fs, err := getStructFields(t)
if err != nil {
return fmt.Errorf("cannot generate encoder for %v: %v", t, err)
}
for _, f := range fs {
if err := g.genStructFieldEncoder(t, f); err != nil {
return err
}
}
fmt.Fprintln(g.out, " out.RawByte('}')")
fmt.Fprintln(g.out, "}")
return nil
}
func (g *Generator) genStructMarshaler(t reflect.Type) error {
switch t.Kind() {
case reflect.Slice, reflect.Array, reflect.Map, reflect.Struct:
default:
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice/array/map type", t)
}
fname := g.getEncoderName(t)
typ := g.getType(t)
if !g.noStdMarshalers {
fmt.Fprintln(g.out, "// MarshalJSON supports json.Marshaler interface")
fmt.Fprintln(g.out, "func (v "+typ+") MarshalJSON() ([]byte, error) {")
fmt.Fprintln(g.out, " w := jwriter.Writer{}")
fmt.Fprintln(g.out, " "+fname+"(&w, v)")
fmt.Fprintln(g.out, " return w.Buffer.BuildBytes(), w.Error")
fmt.Fprintln(g.out, "}")
}
fmt.Fprintln(g.out, "// MarshalEasyJSON supports easyjson.Marshaler interface")
fmt.Fprintln(g.out, "func (v "+typ+") MarshalEasyJSON(w *jwriter.Writer) {")
fmt.Fprintln(g.out, " "+fname+"(w, v)")
fmt.Fprintln(g.out, "}")
return nil
}

449
vendor/github.com/mailru/easyjson/gen/generator.go generated vendored Normal file
View file

@ -0,0 +1,449 @@
package gen
import (
"bytes"
"fmt"
"hash/fnv"
"io"
"path"
"reflect"
"sort"
"strconv"
"strings"
"unicode"
)
const pkgWriter = "github.com/mailru/easyjson/jwriter"
const pkgLexer = "github.com/mailru/easyjson/jlexer"
const pkgEasyJSON = "github.com/mailru/easyjson"
// FieldNamer defines a policy for generating names for struct fields.
type FieldNamer interface {
GetJSONFieldName(t reflect.Type, f reflect.StructField) string
}
// Generator generates the requested marshaler/unmarshalers.
type Generator struct {
out *bytes.Buffer
pkgName string
pkgPath string
buildTags string
hashString string
varCounter int
noStdMarshalers bool
omitEmpty bool
fieldNamer FieldNamer
// package path to local alias map for tracking imports
imports map[string]string
// types that marshalers were requested for by user
marshalers map[reflect.Type]bool
// types that encoders were already generated for
typesSeen map[reflect.Type]bool
// types that encoders were requested for (e.g. by encoders of other types)
typesUnseen []reflect.Type
// function name to relevant type maps to track names of de-/encoders in
// case of a name clash or unnamed structs
functionNames map[string]reflect.Type
}
// NewGenerator initializes and returns a Generator.
func NewGenerator(filename string) *Generator {
ret := &Generator{
imports: map[string]string{
pkgWriter: "jwriter",
pkgLexer: "jlexer",
pkgEasyJSON: "easyjson",
"encoding/json": "json",
},
fieldNamer: DefaultFieldNamer{},
marshalers: make(map[reflect.Type]bool),
typesSeen: make(map[reflect.Type]bool),
functionNames: make(map[string]reflect.Type),
}
// Use a file-unique prefix on all auxiliary funcs to avoid
// name clashes.
hash := fnv.New32()
hash.Write([]byte(filename))
ret.hashString = fmt.Sprintf("%x", hash.Sum32())
return ret
}
// SetPkg sets the name and path of output package.
func (g *Generator) SetPkg(name, path string) {
g.pkgName = name
g.pkgPath = path
}
// SetBuildTags sets build tags for the output file.
func (g *Generator) SetBuildTags(tags string) {
g.buildTags = tags
}
// SetFieldNamer sets field naming strategy.
func (g *Generator) SetFieldNamer(n FieldNamer) {
g.fieldNamer = n
}
// UseSnakeCase sets snake_case field naming strategy.
func (g *Generator) UseSnakeCase() {
g.fieldNamer = SnakeCaseFieldNamer{}
}
// NoStdMarshalers instructs not to generate standard MarshalJSON/UnmarshalJSON
// methods (only the custom interface).
func (g *Generator) NoStdMarshalers() {
g.noStdMarshalers = true
}
// OmitEmpty triggers `json=",omitempty"` behaviour by default.
func (g *Generator) OmitEmpty() {
g.omitEmpty = true
}
// addTypes requests to generate encoding/decoding funcs for the given type.
func (g *Generator) addType(t reflect.Type) {
if g.typesSeen[t] {
return
}
for _, t1 := range g.typesUnseen {
if t1 == t {
return
}
}
g.typesUnseen = append(g.typesUnseen, t)
}
// Add requests to generate marshaler/unmarshalers and encoding/decoding
// funcs for the type of given object.
func (g *Generator) Add(obj interface{}) {
t := reflect.TypeOf(obj)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
g.addType(t)
g.marshalers[t] = true
}
// printHeader prints package declaration and imports.
func (g *Generator) printHeader() {
if g.buildTags != "" {
fmt.Println("// +build ", g.buildTags)
fmt.Println()
}
fmt.Println("// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.")
fmt.Println()
fmt.Println("package ", g.pkgName)
fmt.Println()
byAlias := map[string]string{}
var aliases []string
for path, alias := range g.imports {
aliases = append(aliases, alias)
byAlias[alias] = path
}
sort.Strings(aliases)
fmt.Println("import (")
for _, alias := range aliases {
fmt.Printf(" %s %q\n", alias, byAlias[alias])
}
fmt.Println(")")
fmt.Println("")
fmt.Println("// suppress unused package warning")
fmt.Println("var (")
fmt.Println(" _ *json.RawMessage")
fmt.Println(" _ *jlexer.Lexer")
fmt.Println(" _ *jwriter.Writer")
fmt.Println(" _ easyjson.Marshaler")
fmt.Println(")")
fmt.Println()
}
// Run runs the generator and outputs generated code to out.
func (g *Generator) Run(out io.Writer) error {
g.out = &bytes.Buffer{}
for len(g.typesUnseen) > 0 {
t := g.typesUnseen[len(g.typesUnseen)-1]
g.typesUnseen = g.typesUnseen[:len(g.typesUnseen)-1]
g.typesSeen[t] = true
if err := g.genDecoder(t); err != nil {
return err
}
if err := g.genEncoder(t); err != nil {
return err
}
if !g.marshalers[t] {
continue
}
if err := g.genStructMarshaler(t); err != nil {
return err
}
if err := g.genStructUnmarshaler(t); err != nil {
return err
}
}
g.printHeader()
_, err := out.Write(g.out.Bytes())
return err
}
// fixes vendored paths
func fixPkgPathVendoring(pkgPath string) string {
const vendor = "/vendor/"
if i := strings.LastIndex(pkgPath, vendor); i != -1 {
return pkgPath[i+len(vendor):]
}
return pkgPath
}
func fixAliasName(alias string) string {
alias = strings.Replace(
strings.Replace(alias, ".", "_", -1),
"-",
"_",
-1,
)
return alias
}
// pkgAlias creates and returns and import alias for a given package.
func (g *Generator) pkgAlias(pkgPath string) string {
pkgPath = fixPkgPathVendoring(pkgPath)
if alias := g.imports[pkgPath]; alias != "" {
return alias
}
for i := 0; ; i++ {
alias := fixAliasName(path.Base(pkgPath))
if i > 0 {
alias += fmt.Sprint(i)
}
exists := false
for _, v := range g.imports {
if v == alias {
exists = true
break
}
}
if !exists {
g.imports[pkgPath] = alias
return alias
}
}
}
// getType return the textual type name of given type that can be used in generated code.
func (g *Generator) getType(t reflect.Type) string {
if t.Name() == "" {
switch t.Kind() {
case reflect.Ptr:
return "*" + g.getType(t.Elem())
case reflect.Slice:
return "[]" + g.getType(t.Elem())
case reflect.Array:
return "[" + strconv.Itoa(t.Len()) + "]" + g.getType(t.Elem())
case reflect.Map:
return "map[" + g.getType(t.Key()) + "]" + g.getType(t.Elem())
}
}
if t.Name() == "" || t.PkgPath() == "" {
if t.Kind() == reflect.Struct {
// the fields of an anonymous struct can have named types,
// and t.String() will not be sufficient because it does not
// remove the package name when it matches g.pkgPath.
// so we convert by hand
nf := t.NumField()
lines := make([]string, 0, nf)
for i := 0; i < nf; i++ {
f := t.Field(i)
line := f.Name + " " + g.getType(f.Type)
t := f.Tag
if t != "" {
line += " " + escapeTag(t)
}
lines = append(lines, line)
}
return strings.Join([]string{"struct { ", strings.Join(lines, "; "), " }"}, "")
}
return t.String()
} else if t.PkgPath() == g.pkgPath {
return t.Name()
}
return g.pkgAlias(t.PkgPath()) + "." + t.Name()
}
// escape a struct field tag string back to source code
func escapeTag(tag reflect.StructTag) string {
t := string(tag)
if strings.ContainsRune(t, '`') {
// there are ` in the string; we can't use ` to enclose the string
return strconv.Quote(t)
}
return "`" + t + "`"
}
// uniqueVarName returns a file-unique name that can be used for generated variables.
func (g *Generator) uniqueVarName() string {
g.varCounter++
return fmt.Sprint("v", g.varCounter)
}
// safeName escapes unsafe characters in pkg/type name and returns a string that can be used
// in encoder/decoder names for the type.
func (g *Generator) safeName(t reflect.Type) string {
name := t.PkgPath()
if t.Name() == "" {
name += "anonymous"
} else {
name += "." + t.Name()
}
parts := []string{}
part := []rune{}
for _, c := range name {
if unicode.IsLetter(c) || unicode.IsDigit(c) {
part = append(part, c)
} else if len(part) > 0 {
parts = append(parts, string(part))
part = []rune{}
}
}
return joinFunctionNameParts(false, parts...)
}
// functionName returns a function name for a given type with a given prefix. If a function
// with this prefix already exists for a type, it is returned.
//
// Method is used to track encoder/decoder names for the type.
func (g *Generator) functionName(prefix string, t reflect.Type) string {
prefix = joinFunctionNameParts(true, "easyjson", g.hashString, prefix)
name := joinFunctionNameParts(true, prefix, g.safeName(t))
// Most of the names will be unique, try a shortcut first.
if e, ok := g.functionNames[name]; !ok || e == t {
g.functionNames[name] = t
return name
}
// Search if the function already exists.
for name1, t1 := range g.functionNames {
if t1 == t && strings.HasPrefix(name1, prefix) {
return name1
}
}
// Create a new name in the case of a clash.
for i := 1; ; i++ {
nm := fmt.Sprint(name, i)
if _, ok := g.functionNames[nm]; ok {
continue
}
g.functionNames[nm] = t
return nm
}
}
// DefaultFieldsNamer implements trivial naming policy equivalent to encoding/json.
type DefaultFieldNamer struct{}
func (DefaultFieldNamer) GetJSONFieldName(t reflect.Type, f reflect.StructField) string {
jsonName := strings.Split(f.Tag.Get("json"), ",")[0]
if jsonName != "" {
return jsonName
} else {
return f.Name
}
}
// SnakeCaseFieldNamer implements CamelCase to snake_case conversion for fields names.
type SnakeCaseFieldNamer struct{}
func camelToSnake(name string) string {
var ret bytes.Buffer
multipleUpper := false
var lastUpper rune
var beforeUpper rune
for _, c := range name {
// Non-lowercase character after uppercase is considered to be uppercase too.
isUpper := (unicode.IsUpper(c) || (lastUpper != 0 && !unicode.IsLower(c)))
if lastUpper != 0 {
// Output a delimiter if last character was either the first uppercase character
// in a row, or the last one in a row (e.g. 'S' in "HTTPServer").
// Do not output a delimiter at the beginning of the name.
firstInRow := !multipleUpper
lastInRow := !isUpper
if ret.Len() > 0 && (firstInRow || lastInRow) && beforeUpper != '_' {
ret.WriteByte('_')
}
ret.WriteRune(unicode.ToLower(lastUpper))
}
// Buffer uppercase char, do not output it yet as a delimiter may be required if the
// next character is lowercase.
if isUpper {
multipleUpper = (lastUpper != 0)
lastUpper = c
continue
}
ret.WriteRune(c)
lastUpper = 0
beforeUpper = c
multipleUpper = false
}
if lastUpper != 0 {
ret.WriteRune(unicode.ToLower(lastUpper))
}
return string(ret.Bytes())
}
func (SnakeCaseFieldNamer) GetJSONFieldName(t reflect.Type, f reflect.StructField) string {
jsonName := strings.Split(f.Tag.Get("json"), ",")[0]
if jsonName != "" {
return jsonName
}
return camelToSnake(f.Name)
}
func joinFunctionNameParts(keepFirst bool, parts ...string) string {
buf := bytes.NewBufferString("")
for i, part := range parts {
if i == 0 && keepFirst {
buf.WriteString(part)
} else {
if len(part) > 0 {
buf.WriteString(strings.ToUpper(string(part[0])))
}
if len(part) > 1 {
buf.WriteString(part[1:])
}
}
}
return buf.String()
}

View file

@ -0,0 +1,65 @@
package gen
import (
"testing"
)
func TestCamelToSnake(t *testing.T) {
for i, test := range []struct {
In, Out string
}{
{"", ""},
{"A", "a"},
{"SimpleExample", "simple_example"},
{"internalField", "internal_field"},
{"SomeHTTPStuff", "some_http_stuff"},
{"WriteJSON", "write_json"},
{"HTTP2Server", "http2_server"},
{"Some_Mixed_Case", "some_mixed_case"},
{"do_nothing", "do_nothing"},
{"JSONHTTPRPCServer", "jsonhttprpc_server"}, // nothing can be done here without a dictionary
} {
got := camelToSnake(test.In)
if got != test.Out {
t.Errorf("[%d] camelToSnake(%s) = %s; want %s", i, test.In, got, test.Out)
}
}
}
func TestJoinFunctionNameParts(t *testing.T) {
for i, test := range []struct {
keepFirst bool
parts []string
out string
}{
{false, []string{}, ""},
{false, []string{"a"}, "A"},
{false, []string{"simple", "example"}, "SimpleExample"},
{true, []string{"first", "example"}, "firstExample"},
{false, []string{"some", "UPPER", "case"}, "SomeUPPERCase"},
{false, []string{"number", "123"}, "Number123"},
} {
got := joinFunctionNameParts(test.keepFirst, test.parts...)
if got != test.out {
t.Errorf("[%d] joinFunctionNameParts(%v) = %s; want %s", i, test.parts, got, test.out)
}
}
}
func TestFixVendorPath(t *testing.T) {
for i, test := range []struct {
In, Out string
}{
{"", ""},
{"time", "time"},
{"project/vendor/subpackage", "subpackage"},
} {
got := fixPkgPathVendoring(test.In)
if got != test.Out {
t.Errorf("[%d] fixPkgPathVendoring(%s) = %s; want %s", i, test.In, got, test.Out)
}
}
}

78
vendor/github.com/mailru/easyjson/helpers.go generated vendored Normal file
View file

@ -0,0 +1,78 @@
// Package easyjson contains marshaler/unmarshaler interfaces and helper functions.
package easyjson
import (
"io"
"io/ioutil"
"net/http"
"strconv"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// Marshaler is an easyjson-compatible marshaler interface.
type Marshaler interface {
MarshalEasyJSON(w *jwriter.Writer)
}
// Marshaler is an easyjson-compatible unmarshaler interface.
type Unmarshaler interface {
UnmarshalEasyJSON(w *jlexer.Lexer)
}
// Optional defines an undefined-test method for a type to integrate with 'omitempty' logic.
type Optional interface {
IsDefined() bool
}
// Marshal returns data as a single byte slice. Method is suboptimal as the data is likely to be copied
// from a chain of smaller chunks.
func Marshal(v Marshaler) ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.BuildBytes()
}
// MarshalToWriter marshals the data to an io.Writer.
func MarshalToWriter(v Marshaler, w io.Writer) (written int, err error) {
jw := jwriter.Writer{}
v.MarshalEasyJSON(&jw)
return jw.DumpTo(w)
}
// MarshalToHTTPResponseWriter sets Content-Length and Content-Type headers for the
// http.ResponseWriter, and send the data to the writer. started will be equal to
// false if an error occurred before any http.ResponseWriter methods were actually
// invoked (in this case a 500 reply is possible).
func MarshalToHTTPResponseWriter(v Marshaler, w http.ResponseWriter) (started bool, written int, err error) {
jw := jwriter.Writer{}
v.MarshalEasyJSON(&jw)
if jw.Error != nil {
return false, 0, jw.Error
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Content-Length", strconv.Itoa(jw.Size()))
started = true
written, err = jw.DumpTo(w)
return
}
// Unmarshal decodes the JSON in data into the object.
func Unmarshal(data []byte, v Unmarshaler) error {
l := jlexer.Lexer{Data: data}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// UnmarshalFromReader reads all the data in the reader and decodes as JSON into the object.
func UnmarshalFromReader(r io.Reader, v Unmarshaler) error {
data, err := ioutil.ReadAll(r)
if err != nil {
return err
}
l := jlexer.Lexer{Data: data}
v.UnmarshalEasyJSON(&l)
return l.Error()
}

24
vendor/github.com/mailru/easyjson/jlexer/bytestostr.go generated vendored Normal file
View file

@ -0,0 +1,24 @@
// This file will only be included to the build if neither
// easyjson_nounsafe nor appengine build tag is set. See README notes
// for more details.
//+build !easyjson_nounsafe
//+build !appengine
package jlexer
import (
"reflect"
"unsafe"
)
// bytesToStr creates a string pointing at the slice to avoid copying.
//
// Warning: the string returned by the function should be used with care, as the whole input data
// chunk may be either blocked from being freed by GC because of a single string or the buffer.Data
// may be garbage-collected even when the string exists.
func bytesToStr(data []byte) string {
h := (*reflect.SliceHeader)(unsafe.Pointer(&data))
shdr := reflect.StringHeader{Data: h.Data, Len: h.Len}
return *(*string)(unsafe.Pointer(&shdr))
}

View file

@ -0,0 +1,13 @@
// This file is included to the build if any of the buildtags below
// are defined. Refer to README notes for more details.
//+build easyjson_nounsafe appengine
package jlexer
// bytesToStr creates a string normally from []byte
//
// Note that this method is roughly 1.5x slower than using the 'unsafe' method.
func bytesToStr(data []byte) string {
return string(data)
}

15
vendor/github.com/mailru/easyjson/jlexer/error.go generated vendored Normal file
View file

@ -0,0 +1,15 @@
package jlexer
import "fmt"
// LexerError implements the error interface and represents all possible errors that can be
// generated during parsing the JSON data.
type LexerError struct {
Reason string
Offset int
Data string
}
func (l *LexerError) Error() string {
return fmt.Sprintf("parse error: %s near offset %d of '%s'", l.Reason, l.Offset, l.Data)
}

1114
vendor/github.com/mailru/easyjson/jlexer/lexer.go generated vendored Normal file

File diff suppressed because it is too large Load diff

251
vendor/github.com/mailru/easyjson/jlexer/lexer_test.go generated vendored Normal file
View file

@ -0,0 +1,251 @@
package jlexer
import (
"bytes"
"reflect"
"testing"
)
func TestString(t *testing.T) {
for i, test := range []struct {
toParse string
want string
wantError bool
}{
{toParse: `"simple string"`, want: "simple string"},
{toParse: " \r\r\n\t " + `"test"`, want: "test"},
{toParse: `"\n\t\"\/\\\f\r"`, want: "\n\t\"/\\\f\r"},
{toParse: `"\u0020"`, want: " "},
{toParse: `"\u0020-\t"`, want: " -\t"},
{toParse: `"\ufffd\uFFFD"`, want: "\ufffd\ufffd"},
{toParse: `"\ud83d\ude00"`, want: "😀"},
{toParse: `"\ud83d\ude08"`, want: "😈"},
{toParse: `"\ud8"`, wantError: true},
{toParse: `"test"junk`, want: "test"},
{toParse: `5`, wantError: true}, // not a string
{toParse: `"\x"`, wantError: true}, // invalid escape
{toParse: `"\ud800"`, want: "<22>"}, // invalid utf-8 char; return replacement char
} {
l := Lexer{Data: []byte(test.toParse)}
got := l.String()
if got != test.want {
t.Errorf("[%d, %q] String() = %v; want %v", i, test.toParse, got, test.want)
}
err := l.Error()
if err != nil && !test.wantError {
t.Errorf("[%d, %q] String() error: %v", i, test.toParse, err)
} else if err == nil && test.wantError {
t.Errorf("[%d, %q] String() ok; want error", i, test.toParse)
}
}
}
func TestBytes(t *testing.T) {
for i, test := range []struct {
toParse string
want string
wantError bool
}{
{toParse: `"c2ltcGxlIHN0cmluZw=="`, want: "simple string"},
{toParse: " \r\r\n\t " + `"dGVzdA=="`, want: "test"},
{toParse: `5`, wantError: true}, // not a JSON string
{toParse: `"foobar"`, wantError: true}, // not base64 encoded
{toParse: `"c2ltcGxlIHN0cmluZw="`, wantError: true}, // invalid base64 padding
} {
l := Lexer{Data: []byte(test.toParse)}
got := l.Bytes()
if bytes.Compare(got, []byte(test.want)) != 0 {
t.Errorf("[%d, %q] Bytes() = %v; want: %v", i, test.toParse, got, []byte(test.want))
}
err := l.Error()
if err != nil && !test.wantError {
t.Errorf("[%d, %q] Bytes() error: %v", i, test.toParse, err)
} else if err == nil && test.wantError {
t.Errorf("[%d, %q] Bytes() ok; want error", i, test.toParse)
}
}
}
func TestNumber(t *testing.T) {
for i, test := range []struct {
toParse string
want string
wantError bool
}{
{toParse: "123", want: "123"},
{toParse: "-123", want: "-123"},
{toParse: "\r\n12.35", want: "12.35"},
{toParse: "12.35e+1", want: "12.35e+1"},
{toParse: "12.35e-15", want: "12.35e-15"},
{toParse: "12.35E-15", want: "12.35E-15"},
{toParse: "12.35E15", want: "12.35E15"},
{toParse: `"a"`, wantError: true},
{toParse: "123junk", wantError: true},
{toParse: "1.2.3", wantError: true},
{toParse: "1e2e3", wantError: true},
{toParse: "1e2.3", wantError: true},
} {
l := Lexer{Data: []byte(test.toParse)}
got := l.number()
if got != test.want {
t.Errorf("[%d, %q] number() = %v; want %v", i, test.toParse, got, test.want)
}
err := l.Error()
if err != nil && !test.wantError {
t.Errorf("[%d, %q] number() error: %v", i, test.toParse, err)
} else if err == nil && test.wantError {
t.Errorf("[%d, %q] number() ok; want error", i, test.toParse)
}
}
}
func TestBool(t *testing.T) {
for i, test := range []struct {
toParse string
want bool
wantError bool
}{
{toParse: "true", want: true},
{toParse: "false", want: false},
{toParse: "1", wantError: true},
{toParse: "truejunk", wantError: true},
{toParse: `false"junk"`, wantError: true},
{toParse: "True", wantError: true},
{toParse: "False", wantError: true},
} {
l := Lexer{Data: []byte(test.toParse)}
got := l.Bool()
if got != test.want {
t.Errorf("[%d, %q] Bool() = %v; want %v", i, test.toParse, got, test.want)
}
err := l.Error()
if err != nil && !test.wantError {
t.Errorf("[%d, %q] Bool() error: %v", i, test.toParse, err)
} else if err == nil && test.wantError {
t.Errorf("[%d, %q] Bool() ok; want error", i, test.toParse)
}
}
}
func TestSkipRecursive(t *testing.T) {
for i, test := range []struct {
toParse string
left string
wantError bool
}{
{toParse: "5, 4", left: ", 4"},
{toParse: "[5, 6], 4", left: ", 4"},
{toParse: "[5, [7,8]]: 4", left: ": 4"},
{toParse: `{"a":1}, 4`, left: ", 4"},
{toParse: `{"a":1, "b":{"c": 5}, "e":[12,15]}, 4`, left: ", 4"},
// array start/end chars in a string
{toParse: `[5, "]"], 4`, left: ", 4"},
{toParse: `[5, "\"]"], 4`, left: ", 4"},
{toParse: `[5, "["], 4`, left: ", 4"},
{toParse: `[5, "\"["], 4`, left: ", 4"},
// object start/end chars in a string
{toParse: `{"a}":1}, 4`, left: ", 4"},
{toParse: `{"a\"}":1}, 4`, left: ", 4"},
{toParse: `{"a{":1}, 4`, left: ", 4"},
{toParse: `{"a\"{":1}, 4`, left: ", 4"},
// object with double slashes at the end of string
{toParse: `{"a":"hey\\"}, 4`, left: ", 4"},
} {
l := Lexer{Data: []byte(test.toParse)}
l.SkipRecursive()
got := string(l.Data[l.pos:])
if got != test.left {
t.Errorf("[%d, %q] SkipRecursive() left = %v; want %v", i, test.toParse, got, test.left)
}
err := l.Error()
if err != nil && !test.wantError {
t.Errorf("[%d, %q] SkipRecursive() error: %v", i, test.toParse, err)
} else if err == nil && test.wantError {
t.Errorf("[%d, %q] SkipRecursive() ok; want error", i, test.toParse)
}
}
}
func TestInterface(t *testing.T) {
for i, test := range []struct {
toParse string
want interface{}
wantError bool
}{
{toParse: "null", want: nil},
{toParse: "true", want: true},
{toParse: `"a"`, want: "a"},
{toParse: "5", want: float64(5)},
{toParse: `{}`, want: map[string]interface{}{}},
{toParse: `[]`, want: []interface{}(nil)},
{toParse: `{"a": "b"}`, want: map[string]interface{}{"a": "b"}},
{toParse: `[5]`, want: []interface{}{float64(5)}},
{toParse: `{"a":5 , "b" : "string"}`, want: map[string]interface{}{"a": float64(5), "b": "string"}},
{toParse: `["a", 5 , null, true]`, want: []interface{}{"a", float64(5), nil, true}},
{toParse: `{"a" "b"}`, wantError: true},
{toParse: `{"a": "b",}`, wantError: true},
{toParse: `{"a":"b","c" "b"}`, wantError: true},
{toParse: `{"a": "b","c":"d",}`, wantError: true},
{toParse: `{,}`, wantError: true},
{toParse: `[1, 2,]`, wantError: true},
{toParse: `[1 2]`, wantError: true},
{toParse: `[,]`, wantError: true},
} {
l := Lexer{Data: []byte(test.toParse)}
got := l.Interface()
if !reflect.DeepEqual(got, test.want) {
t.Errorf("[%d, %q] Interface() = %v; want %v", i, test.toParse, got, test.want)
}
err := l.Error()
if err != nil && !test.wantError {
t.Errorf("[%d, %q] Interface() error: %v", i, test.toParse, err)
} else if err == nil && test.wantError {
t.Errorf("[%d, %q] Interface() ok; want error", i, test.toParse)
}
}
}
func TestConsumed(t *testing.T) {
for i, test := range []struct {
toParse string
wantError bool
}{
{toParse: "", wantError: false},
{toParse: " ", wantError: false},
{toParse: "\r\n", wantError: false},
{toParse: "\t\t", wantError: false},
{toParse: "{", wantError: true},
} {
l := Lexer{Data: []byte(test.toParse)}
l.Consumed()
err := l.Error()
if err != nil && !test.wantError {
t.Errorf("[%d, %q] Consumed() error: %v", i, test.toParse, err)
} else if err == nil && test.wantError {
t.Errorf("[%d, %q] Consumed() ok; want error", i, test.toParse)
}
}
}

328
vendor/github.com/mailru/easyjson/jwriter/writer.go generated vendored Normal file
View file

@ -0,0 +1,328 @@
// Package jwriter contains a JSON writer.
package jwriter
import (
"encoding/base64"
"io"
"strconv"
"unicode/utf8"
"github.com/mailru/easyjson/buffer"
)
// Flags describe various encoding options. The behavior may be actually implemented in the encoder, but
// Flags field in Writer is used to set and pass them around.
type Flags int
const (
NilMapAsEmpty Flags = 1 << iota // Encode nil map as '{}' rather than 'null'.
NilSliceAsEmpty // Encode nil slice as '[]' rather than 'null'.
)
// Writer is a JSON writer.
type Writer struct {
Flags Flags
Error error
Buffer buffer.Buffer
NoEscapeHTML bool
}
// Size returns the size of the data that was written out.
func (w *Writer) Size() int {
return w.Buffer.Size()
}
// DumpTo outputs the data to given io.Writer, resetting the buffer.
func (w *Writer) DumpTo(out io.Writer) (written int, err error) {
return w.Buffer.DumpTo(out)
}
// BuildBytes returns writer data as a single byte slice. You can optionally provide one byte slice
// as argument that it will try to reuse.
func (w *Writer) BuildBytes(reuse ...[]byte) ([]byte, error) {
if w.Error != nil {
return nil, w.Error
}
return w.Buffer.BuildBytes(reuse...), nil
}
// ReadCloser returns an io.ReadCloser that can be used to read the data.
// ReadCloser also resets the buffer.
func (w *Writer) ReadCloser() (io.ReadCloser, error) {
if w.Error != nil {
return nil, w.Error
}
return w.Buffer.ReadCloser(), nil
}
// RawByte appends raw binary data to the buffer.
func (w *Writer) RawByte(c byte) {
w.Buffer.AppendByte(c)
}
// RawByte appends raw binary data to the buffer.
func (w *Writer) RawString(s string) {
w.Buffer.AppendString(s)
}
// Raw appends raw binary data to the buffer or sets the error if it is given. Useful for
// calling with results of MarshalJSON-like functions.
func (w *Writer) Raw(data []byte, err error) {
switch {
case w.Error != nil:
return
case err != nil:
w.Error = err
case len(data) > 0:
w.Buffer.AppendBytes(data)
default:
w.RawString("null")
}
}
// RawText encloses raw binary data in quotes and appends in to the buffer.
// Useful for calling with results of MarshalText-like functions.
func (w *Writer) RawText(data []byte, err error) {
switch {
case w.Error != nil:
return
case err != nil:
w.Error = err
case len(data) > 0:
w.String(string(data))
default:
w.RawString("null")
}
}
// Base64Bytes appends data to the buffer after base64 encoding it
func (w *Writer) Base64Bytes(data []byte) {
if data == nil {
w.Buffer.AppendString("null")
return
}
w.Buffer.AppendByte('"')
dst := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
base64.StdEncoding.Encode(dst, data)
w.Buffer.AppendBytes(dst)
w.Buffer.AppendByte('"')
}
func (w *Writer) Uint8(n uint8) {
w.Buffer.EnsureSpace(3)
w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
}
func (w *Writer) Uint16(n uint16) {
w.Buffer.EnsureSpace(5)
w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
}
func (w *Writer) Uint32(n uint32) {
w.Buffer.EnsureSpace(10)
w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
}
func (w *Writer) Uint(n uint) {
w.Buffer.EnsureSpace(20)
w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
}
func (w *Writer) Uint64(n uint64) {
w.Buffer.EnsureSpace(20)
w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, n, 10)
}
func (w *Writer) Int8(n int8) {
w.Buffer.EnsureSpace(4)
w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
}
func (w *Writer) Int16(n int16) {
w.Buffer.EnsureSpace(6)
w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
}
func (w *Writer) Int32(n int32) {
w.Buffer.EnsureSpace(11)
w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
}
func (w *Writer) Int(n int) {
w.Buffer.EnsureSpace(21)
w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
}
func (w *Writer) Int64(n int64) {
w.Buffer.EnsureSpace(21)
w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, n, 10)
}
func (w *Writer) Uint8Str(n uint8) {
w.Buffer.EnsureSpace(3)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}
func (w *Writer) Uint16Str(n uint16) {
w.Buffer.EnsureSpace(5)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}
func (w *Writer) Uint32Str(n uint32) {
w.Buffer.EnsureSpace(10)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}
func (w *Writer) UintStr(n uint) {
w.Buffer.EnsureSpace(20)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}
func (w *Writer) Uint64Str(n uint64) {
w.Buffer.EnsureSpace(20)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, n, 10)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}
func (w *Writer) Int8Str(n int8) {
w.Buffer.EnsureSpace(4)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}
func (w *Writer) Int16Str(n int16) {
w.Buffer.EnsureSpace(6)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}
func (w *Writer) Int32Str(n int32) {
w.Buffer.EnsureSpace(11)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}
func (w *Writer) IntStr(n int) {
w.Buffer.EnsureSpace(21)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}
func (w *Writer) Int64Str(n int64) {
w.Buffer.EnsureSpace(21)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, n, 10)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}
func (w *Writer) Float32(n float32) {
w.Buffer.EnsureSpace(20)
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32)
}
func (w *Writer) Float64(n float64) {
w.Buffer.EnsureSpace(20)
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, n, 'g', -1, 64)
}
func (w *Writer) Bool(v bool) {
w.Buffer.EnsureSpace(5)
if v {
w.Buffer.Buf = append(w.Buffer.Buf, "true"...)
} else {
w.Buffer.Buf = append(w.Buffer.Buf, "false"...)
}
}
const chars = "0123456789abcdef"
func isNotEscapedSingleChar(c byte, escapeHTML bool) bool {
// Note: might make sense to use a table if there are more chars to escape. With 4 chars
// it benchmarks the same.
if escapeHTML {
return c != '<' && c != '>' && c != '&' && c != '\\' && c != '"' && c >= 0x20 && c < utf8.RuneSelf
} else {
return c != '\\' && c != '"' && c >= 0x20 && c < utf8.RuneSelf
}
}
func (w *Writer) String(s string) {
w.Buffer.AppendByte('"')
// Portions of the string that contain no escapes are appended as
// byte slices.
p := 0 // last non-escape symbol
for i := 0; i < len(s); {
c := s[i]
if isNotEscapedSingleChar(c, !w.NoEscapeHTML) {
// single-width character, no escaping is required
i++
continue
} else if c < utf8.RuneSelf {
// single-with character, need to escape
w.Buffer.AppendString(s[p:i])
switch c {
case '\t':
w.Buffer.AppendString(`\t`)
case '\r':
w.Buffer.AppendString(`\r`)
case '\n':
w.Buffer.AppendString(`\n`)
case '\\':
w.Buffer.AppendString(`\\`)
case '"':
w.Buffer.AppendString(`\"`)
default:
w.Buffer.AppendString(`\u00`)
w.Buffer.AppendByte(chars[c>>4])
w.Buffer.AppendByte(chars[c&0xf])
}
i++
p = i
continue
}
// broken utf
runeValue, runeWidth := utf8.DecodeRuneInString(s[i:])
if runeValue == utf8.RuneError && runeWidth == 1 {
w.Buffer.AppendString(s[p:i])
w.Buffer.AppendString(`\ufffd`)
i++
p = i
continue
}
// jsonp stuff - tab separator and line separator
if runeValue == '\u2028' || runeValue == '\u2029' {
w.Buffer.AppendString(s[p:i])
w.Buffer.AppendString(`\u202`)
w.Buffer.AppendByte(chars[runeValue&0xf])
i += runeWidth
p = i
continue
}
i += runeWidth
}
w.Buffer.AppendString(s[p:])
w.Buffer.AppendByte('"')
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Bool struct {
V bool
Defined bool
}
// Creates an optional type with a given value.
func OBool(v bool) Bool {
return Bool{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Bool) Get(deflt bool) bool {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Bool) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Bool(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Bool) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Bool{}
} else {
v.V = l.Bool()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Bool) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Bool) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Bool) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Bool) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Float32 struct {
V float32
Defined bool
}
// Creates an optional type with a given value.
func OFloat32(v float32) Float32 {
return Float32{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Float32) Get(deflt float32) float32 {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Float32) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Float32(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Float32) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Float32{}
} else {
v.V = l.Float32()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Float32) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Float32) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Float32) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Float32) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Float64 struct {
V float64
Defined bool
}
// Creates an optional type with a given value.
func OFloat64(v float64) Float64 {
return Float64{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Float64) Get(deflt float64) float64 {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Float64) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Float64(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Float64) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Float64{}
} else {
v.V = l.Float64()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Float64) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Float64) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Float64) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Float64) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Int struct {
V int
Defined bool
}
// Creates an optional type with a given value.
func OInt(v int) Int {
return Int{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Int) Get(deflt int) int {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Int) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Int(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Int) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Int{}
} else {
v.V = l.Int()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Int) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Int) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Int) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Int) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Int16 struct {
V int16
Defined bool
}
// Creates an optional type with a given value.
func OInt16(v int16) Int16 {
return Int16{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Int16) Get(deflt int16) int16 {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Int16) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Int16(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Int16) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Int16{}
} else {
v.V = l.Int16()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Int16) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Int16) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Int16) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Int16) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Int32 struct {
V int32
Defined bool
}
// Creates an optional type with a given value.
func OInt32(v int32) Int32 {
return Int32{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Int32) Get(deflt int32) int32 {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Int32) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Int32(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Int32) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Int32{}
} else {
v.V = l.Int32()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Int32) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Int32) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Int32) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Int32) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Int64 struct {
V int64
Defined bool
}
// Creates an optional type with a given value.
func OInt64(v int64) Int64 {
return Int64{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Int64) Get(deflt int64) int64 {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Int64) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Int64(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Int64) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Int64{}
} else {
v.V = l.Int64()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Int64) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Int64) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Int64) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Int64) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Int8 struct {
V int8
Defined bool
}
// Creates an optional type with a given value.
func OInt8(v int8) Int8 {
return Int8{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Int8) Get(deflt int8) int8 {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Int8) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Int8(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Int8) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Int8{}
} else {
v.V = l.Int8()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Int8) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Int8) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Int8) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Int8) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type String struct {
V string
Defined bool
}
// Creates an optional type with a given value.
func OString(v string) String {
return String{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v String) Get(deflt string) string {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v String) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.String(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *String) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = String{}
} else {
v.V = l.String()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *String) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *String) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v String) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v String) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Uint struct {
V uint
Defined bool
}
// Creates an optional type with a given value.
func OUint(v uint) Uint {
return Uint{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Uint) Get(deflt uint) uint {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Uint) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Uint(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Uint) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Uint{}
} else {
v.V = l.Uint()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Uint) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Uint) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Uint) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Uint) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Uint16 struct {
V uint16
Defined bool
}
// Creates an optional type with a given value.
func OUint16(v uint16) Uint16 {
return Uint16{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Uint16) Get(deflt uint16) uint16 {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Uint16) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Uint16(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Uint16) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Uint16{}
} else {
v.V = l.Uint16()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Uint16) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Uint16) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Uint16) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Uint16) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Uint32 struct {
V uint32
Defined bool
}
// Creates an optional type with a given value.
func OUint32(v uint32) Uint32 {
return Uint32{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Uint32) Get(deflt uint32) uint32 {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Uint32) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Uint32(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Uint32) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Uint32{}
} else {
v.V = l.Uint32()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Uint32) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Uint32) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Uint32) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Uint32) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Uint64 struct {
V uint64
Defined bool
}
// Creates an optional type with a given value.
func OUint64(v uint64) Uint64 {
return Uint64{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Uint64) Get(deflt uint64) uint64 {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Uint64) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Uint64(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Uint64) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Uint64{}
} else {
v.V = l.Uint64()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Uint64) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Uint64) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Uint64) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Uint64) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

View file

@ -0,0 +1,79 @@
// generated by gotemplate
package opt
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Uint8 struct {
V uint8
Defined bool
}
// Creates an optional type with a given value.
func OUint8(v uint8) Uint8 {
return Uint8{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Uint8) Get(deflt uint8) uint8 {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Uint8) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Uint8(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Uint8) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Uint8{}
} else {
v.V = l.Uint8()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Uint8) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Uint8) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Uint8) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Uint8) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

80
vendor/github.com/mailru/easyjson/opt/optional/opt.go generated vendored Normal file
View file

@ -0,0 +1,80 @@
// +build none
package optional
import (
"fmt"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// template type Optional(A)
type A int
// A 'gotemplate'-based type for providing optional semantics without using pointers.
type Optional struct {
V A
Defined bool
}
// Creates an optional type with a given value.
func OOptional(v A) Optional {
return Optional{V: v, Defined: true}
}
// Get returns the value or given default in the case the value is undefined.
func (v Optional) Get(deflt A) A {
if !v.Defined {
return deflt
}
return v.V
}
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v Optional) MarshalEasyJSON(w *jwriter.Writer) {
if v.Defined {
w.Optional(v.V)
} else {
w.RawString("null")
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *Optional) UnmarshalEasyJSON(l *jlexer.Lexer) {
if l.IsNull() {
l.Skip()
*v = Optional{}
} else {
v.V = l.Optional()
v.Defined = true
}
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Optional) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalJSON implements a standard json marshaler interface.
func (v *Optional) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{}
v.UnmarshalEasyJSON(&l)
return l.Error()
}
// IsDefined returns whether the value is defined, a function is required so that it can
// be used in an interface.
func (v Optional) IsDefined() bool {
return v.Defined
}
// String implements a stringer interface using fmt.Sprint for the value.
func (v Optional) String() string {
if !v.Defined {
return "<undefined>"
}
return fmt.Sprint(v.V)
}

22
vendor/github.com/mailru/easyjson/opt/opts.go generated vendored Normal file
View file

@ -0,0 +1,22 @@
package opt
//go:generate sed -i "s/\\+build none/generated by gotemplate/" optional/opt.go
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Int(int)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Uint(uint)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Int8(int8)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Int16(int16)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Int32(int32)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Int64(int64)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Uint8(uint8)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Uint16(uint16)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Uint32(uint32)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Uint64(uint64)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Float32(float32)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Float64(float64)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" Bool(bool)
//go:generate gotemplate "github.com/mailru/easyjson/opt/optional" String(string)
//go:generate sed -i "s/generated by gotemplate/+build none/" optional/opt.go

91
vendor/github.com/mailru/easyjson/parser/parser.go generated vendored Normal file
View file

@ -0,0 +1,91 @@
package parser
import (
"go/ast"
"go/parser"
"go/token"
"strings"
)
const structComment = "easyjson:json"
type Parser struct {
PkgPath string
PkgName string
StructNames []string
AllStructs bool
}
type visitor struct {
*Parser
name string
explicit bool
}
func (p *Parser) needType(comments string) bool {
for _, v := range strings.Split(comments, "\n") {
if strings.HasPrefix(v, structComment) {
return true
}
}
return false
}
func (v *visitor) Visit(n ast.Node) (w ast.Visitor) {
switch n := n.(type) {
case *ast.Package:
return v
case *ast.File:
v.PkgName = n.Name.String()
return v
case *ast.GenDecl:
v.explicit = v.needType(n.Doc.Text())
if !v.explicit && !v.AllStructs {
return nil
}
return v
case *ast.TypeSpec:
v.name = n.Name.String()
// Allow to specify non-structs explicitly independent of '-all' flag.
if v.explicit {
v.StructNames = append(v.StructNames, v.name)
return nil
}
return v
case *ast.StructType:
v.StructNames = append(v.StructNames, v.name)
return nil
}
return nil
}
func (p *Parser) Parse(fname string, isDir bool) error {
var err error
if p.PkgPath, err = getPkgPath(fname, isDir); err != nil {
return err
}
fset := token.NewFileSet()
if isDir {
packages, err := parser.ParseDir(fset, fname, nil, parser.ParseComments)
if err != nil {
return err
}
for _, pckg := range packages {
ast.Walk(&visitor{Parser: p}, pckg)
}
} else {
f, err := parser.ParseFile(fset, fname, nil, parser.ParseComments)
if err != nil {
return err
}
ast.Walk(&visitor{Parser: p}, f)
}
return nil
}

View file

@ -0,0 +1,33 @@
// +build !windows
package parser
import (
"fmt"
"os"
"path"
"strings"
)
func getPkgPath(fname string, isDir bool) (string, error) {
if !path.IsAbs(fname) {
pwd, err := os.Getwd()
if err != nil {
return "", err
}
fname = path.Join(pwd, fname)
}
for _, p := range strings.Split(os.Getenv("GOPATH"), ":") {
prefix := path.Join(p, "src") + "/"
if rel := strings.TrimPrefix(fname, prefix); rel != fname {
if !isDir {
return path.Dir(rel), nil
} else {
return path.Clean(rel), nil
}
}
}
return "", fmt.Errorf("file '%v' is not in GOPATH", fname)
}

View file

@ -0,0 +1,37 @@
package parser
import (
"fmt"
"os"
"path"
"strings"
)
func normalizePath(path string) string {
return strings.Replace(path, "\\", "/", -1)
}
func getPkgPath(fname string, isDir bool) (string, error) {
if !path.IsAbs(fname) {
pwd, err := os.Getwd()
if err != nil {
return "", err
}
fname = path.Join(pwd, fname)
}
fname = normalizePath(fname)
for _, p := range strings.Split(os.Getenv("GOPATH"), ";") {
prefix := path.Join(normalizePath(p), "src") + "/"
if rel := strings.TrimPrefix(fname, prefix); rel != fname {
if !isDir {
return path.Dir(rel), nil
} else {
return path.Clean(rel), nil
}
}
}
return "", fmt.Errorf("file '%v' is not in GOPATH", fname)
}

45
vendor/github.com/mailru/easyjson/raw.go generated vendored Normal file
View file

@ -0,0 +1,45 @@
package easyjson
import (
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// RawMessage is a raw piece of JSON (number, string, bool, object, array or
// null) that is extracted without parsing and output as is during marshaling.
type RawMessage []byte
// MarshalEasyJSON does JSON marshaling using easyjson interface.
func (v *RawMessage) MarshalEasyJSON(w *jwriter.Writer) {
if len(*v) == 0 {
w.RawString("null")
} else {
w.Raw(*v, nil)
}
}
// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
func (v *RawMessage) UnmarshalEasyJSON(l *jlexer.Lexer) {
*v = RawMessage(l.Raw())
}
// UnmarshalJSON implements encoding/json.Unmarshaler interface.
func (v *RawMessage) UnmarshalJSON(data []byte) error {
*v = data
return nil
}
var nullBytes = []byte("null")
// MarshalJSON implements encoding/json.Marshaler interface.
func (v RawMessage) MarshalJSON() ([]byte, error) {
if len(v) == 0 {
return nullBytes, nil
}
return v, nil
}
// IsDefined is required for integration with omitempty easyjson logic.
func (v *RawMessage) IsDefined() bool {
return len(*v) > 0
}

222
vendor/github.com/mailru/easyjson/tests/basic_test.go generated vendored Normal file
View file

@ -0,0 +1,222 @@
package tests
import (
"reflect"
"testing"
"encoding/json"
"github.com/mailru/easyjson"
"github.com/mailru/easyjson/jwriter"
)
type testType interface {
json.Marshaler
json.Unmarshaler
}
var testCases = []struct {
Decoded testType
Encoded string
}{
{&primitiveTypesValue, primitiveTypesString},
{&namedPrimitiveTypesValue, namedPrimitiveTypesString},
{&structsValue, structsString},
{&omitEmptyValue, omitEmptyString},
{&snakeStructValue, snakeStructString},
{&omitEmptyDefaultValue, omitEmptyDefaultString},
{&optsValue, optsString},
{&rawValue, rawString},
{&stdMarshalerValue, stdMarshalerString},
{&userMarshalerValue, userMarshalerString},
{&unexportedStructValue, unexportedStructString},
{&excludedFieldValue, excludedFieldString},
{&sliceValue, sliceString},
{&arrayValue, arrayString},
{&mapsValue, mapsString},
{&deepNestValue, deepNestString},
{&IntsValue, IntsString},
{&mapStringStringValue, mapStringStringString},
{&namedTypeValue, namedTypeValueString},
}
func TestMarshal(t *testing.T) {
for i, test := range testCases {
data, err := test.Decoded.MarshalJSON()
if err != nil {
t.Errorf("[%d, %T] MarshalJSON() error: %v", i, test.Decoded, err)
}
got := string(data)
if got != test.Encoded {
t.Errorf("[%d, %T] MarshalJSON(): got \n%v\n\t\t want \n%v", i, test.Decoded, got, test.Encoded)
}
}
}
func TestUnmarshal(t *testing.T) {
for i, test := range testCases {
v1 := reflect.New(reflect.TypeOf(test.Decoded).Elem()).Interface()
v := v1.(testType)
err := v.UnmarshalJSON([]byte(test.Encoded))
if err != nil {
t.Errorf("[%d, %T] UnmarshalJSON() error: %v", i, test.Decoded, err)
}
if !reflect.DeepEqual(v, test.Decoded) {
t.Errorf("[%d, %T] UnmarshalJSON(): got \n%+v\n\t\t want \n%+v", i, test.Decoded, v, test.Decoded)
}
}
}
func TestRawMessageSTD(t *testing.T) {
type T struct {
F easyjson.RawMessage
Fnil easyjson.RawMessage
}
val := T{F: easyjson.RawMessage([]byte(`"test"`))}
str := `{"F":"test","Fnil":null}`
data, err := json.Marshal(val)
if err != nil {
t.Errorf("json.Marshal() error: %v", err)
}
got := string(data)
if got != str {
t.Errorf("json.Marshal() = %v; want %v", got, str)
}
wantV := T{F: easyjson.RawMessage([]byte(`"test"`)), Fnil: easyjson.RawMessage([]byte("null"))}
var gotV T
err = json.Unmarshal([]byte(str), &gotV)
if err != nil {
t.Errorf("json.Unmarshal() error: %v", err)
}
if !reflect.DeepEqual(gotV, wantV) {
t.Errorf("json.Unmarshal() = %v; want %v", gotV, wantV)
}
}
func TestParseNull(t *testing.T) {
var got, want SubStruct
if err := easyjson.Unmarshal([]byte("null"), &got); err != nil {
t.Errorf("Unmarshal() error: %v", err)
}
if !reflect.DeepEqual(got, want) {
t.Errorf("Unmarshal() = %+v; want %+v", got, want)
}
}
var testSpecialCases = []struct {
EncodedString string
Value string
}{
{`"Username \u003cuser@example.com\u003e"`, `Username <user@example.com>`},
{`"Username\ufffd"`, "Username\xc5"},
{`естzтест"`, естzтест"},
{`"тест\ufffdтест"`, "тест\xc5тест"},
{`"绿茶"`, "绿茶"},
{`"绿\ufffd茶"`, "绿\xc5茶"},
{`"тест\u2028"`, "тест\xE2\x80\xA8"},
{`"\\\r\n\t\""`, "\\\r\n\t\""},
{`"ü"`, "ü"},
}
func TestSpecialCases(t *testing.T) {
for i, test := range testSpecialCases {
w := jwriter.Writer{}
w.String(test.Value)
got := string(w.Buffer.BuildBytes())
if got != test.EncodedString {
t.Errorf("[%d] Encoded() = %+v; want %+v", i, got, test.EncodedString)
}
}
}
func TestOverflowArray(t *testing.T) {
var a Arrays
err := easyjson.Unmarshal([]byte(arrayOverflowString), &a)
if err != nil {
t.Error(err)
}
if a != arrayValue {
t.Errorf("Unmarshal(%v) = %+v; want %+v", arrayOverflowString, a, arrayValue)
}
}
func TestUnderflowArray(t *testing.T) {
var a Arrays
err := easyjson.Unmarshal([]byte(arrayUnderflowString), &a)
if err != nil {
t.Error(err)
}
if a != arrayUnderflowValue {
t.Errorf("Unmarshal(%v) = %+v; want %+v", arrayUnderflowString, a, arrayUnderflowValue)
}
}
func TestEncodingFlags(t *testing.T) {
for i, test := range []struct {
Flags jwriter.Flags
In easyjson.Marshaler
Want string
}{
{0, EncodingFlagsTestMap{}, `{"F":null}`},
{0, EncodingFlagsTestSlice{}, `{"F":null}`},
{jwriter.NilMapAsEmpty, EncodingFlagsTestMap{}, `{"F":{}}`},
{jwriter.NilSliceAsEmpty, EncodingFlagsTestSlice{}, `{"F":[]}`},
} {
w := &jwriter.Writer{Flags: test.Flags}
test.In.MarshalEasyJSON(w)
data, err := w.BuildBytes()
if err != nil {
t.Errorf("[%v] easyjson.Marshal(%+v) error: %v", i, test.In, err)
}
v := string(data)
if v != test.Want {
t.Errorf("[%v] easyjson.Marshal(%+v) = %v; want %v", i, test.In, v, test.Want)
}
}
}
func TestNestedEasyJsonMarshal(t *testing.T) {
n := map[string]*NestedEasyMarshaler{
"Value": {},
"Slice1": {},
"Slice2": {},
"Map1": {},
"Map2": {},
}
ni := NestedInterfaces{
Value: n["Value"],
Slice: []interface{}{n["Slice1"], n["Slice2"]},
Map: map[string]interface{}{"1": n["Map1"], "2": n["Map2"]},
}
easyjson.Marshal(ni)
for k, v := range n {
if !v.EasilyMarshaled {
t.Errorf("Nested interface %s wasn't easily marshaled", k)
}
}
}
func TestUnmarshalStructWithEmbeddedPtrStruct(t *testing.T) {
var s = StructWithInterface{Field2: &EmbeddedStruct{}}
var err error
err = easyjson.Unmarshal([]byte(structWithInterfaceString), &s)
if err != nil {
t.Errorf("easyjson.Unmarshal() error: %v", err)
}
if !reflect.DeepEqual(s, structWithInterfaceValueFilled) {
t.Errorf("easyjson.Unmarshal() = %#v; want %#v", s, structWithInterfaceValueFilled)
}
}

694
vendor/github.com/mailru/easyjson/tests/data.go generated vendored Normal file
View file

@ -0,0 +1,694 @@
package tests
import (
"fmt"
"math"
"net"
"time"
"github.com/mailru/easyjson"
"github.com/mailru/easyjson/opt"
)
type PrimitiveTypes struct {
String string
Bool bool
Int int
Int8 int8
Int16 int16
Int32 int32
Int64 int64
Uint uint
Uint8 uint8
Uint16 uint16
Uint32 uint32
Uint64 uint64
IntString int `json:",string"`
Int8String int8 `json:",string"`
Int16String int16 `json:",string"`
Int32String int32 `json:",string"`
Int64String int64 `json:",string"`
UintString uint `json:",string"`
Uint8String uint8 `json:",string"`
Uint16String uint16 `json:",string"`
Uint32String uint32 `json:",string"`
Uint64String uint64 `json:",string"`
Float32 float32
Float64 float64
Ptr *string
PtrNil *string
}
var str = "bla"
var primitiveTypesValue = PrimitiveTypes{
String: "test", Bool: true,
Int: math.MinInt32,
Int8: math.MinInt8,
Int16: math.MinInt16,
Int32: math.MinInt32,
Int64: math.MinInt64,
Uint: math.MaxUint32,
Uint8: math.MaxUint8,
Uint16: math.MaxUint16,
Uint32: math.MaxUint32,
Uint64: math.MaxUint64,
IntString: math.MinInt32,
Int8String: math.MinInt8,
Int16String: math.MinInt16,
Int32String: math.MinInt32,
Int64String: math.MinInt64,
UintString: math.MaxUint32,
Uint8String: math.MaxUint8,
Uint16String: math.MaxUint16,
Uint32String: math.MaxUint32,
Uint64String: math.MaxUint64,
Float32: 1.5,
Float64: math.MaxFloat64,
Ptr: &str,
}
var primitiveTypesString = "{" +
`"String":"test","Bool":true,` +
`"Int":` + fmt.Sprint(math.MinInt32) + `,` +
`"Int8":` + fmt.Sprint(math.MinInt8) + `,` +
`"Int16":` + fmt.Sprint(math.MinInt16) + `,` +
`"Int32":` + fmt.Sprint(math.MinInt32) + `,` +
`"Int64":` + fmt.Sprint(int64(math.MinInt64)) + `,` +
`"Uint":` + fmt.Sprint(math.MaxUint32) + `,` +
`"Uint8":` + fmt.Sprint(math.MaxUint8) + `,` +
`"Uint16":` + fmt.Sprint(math.MaxUint16) + `,` +
`"Uint32":` + fmt.Sprint(math.MaxUint32) + `,` +
`"Uint64":` + fmt.Sprint(uint64(math.MaxUint64)) + `,` +
`"IntString":"` + fmt.Sprint(math.MinInt32) + `",` +
`"Int8String":"` + fmt.Sprint(math.MinInt8) + `",` +
`"Int16String":"` + fmt.Sprint(math.MinInt16) + `",` +
`"Int32String":"` + fmt.Sprint(math.MinInt32) + `",` +
`"Int64String":"` + fmt.Sprint(int64(math.MinInt64)) + `",` +
`"UintString":"` + fmt.Sprint(math.MaxUint32) + `",` +
`"Uint8String":"` + fmt.Sprint(math.MaxUint8) + `",` +
`"Uint16String":"` + fmt.Sprint(math.MaxUint16) + `",` +
`"Uint32String":"` + fmt.Sprint(math.MaxUint32) + `",` +
`"Uint64String":"` + fmt.Sprint(uint64(math.MaxUint64)) + `",` +
`"Float32":` + fmt.Sprint(1.5) + `,` +
`"Float64":` + fmt.Sprint(math.MaxFloat64) + `,` +
`"Ptr":"bla",` +
`"PtrNil":null` +
"}"
type (
NamedString string
NamedBool bool
NamedInt int
NamedInt8 int8
NamedInt16 int16
NamedInt32 int32
NamedInt64 int64
NamedUint uint
NamedUint8 uint8
NamedUint16 uint16
NamedUint32 uint32
NamedUint64 uint64
NamedFloat32 float32
NamedFloat64 float64
NamedStrPtr *string
)
type NamedPrimitiveTypes struct {
String NamedString
Bool NamedBool
Int NamedInt
Int8 NamedInt8
Int16 NamedInt16
Int32 NamedInt32
Int64 NamedInt64
Uint NamedUint
Uint8 NamedUint8
Uint16 NamedUint16
Uint32 NamedUint32
Uint64 NamedUint64
Float32 NamedFloat32
Float64 NamedFloat64
Ptr NamedStrPtr
PtrNil NamedStrPtr
}
var namedPrimitiveTypesValue = NamedPrimitiveTypes{
String: "test",
Bool: true,
Int: math.MinInt32,
Int8: math.MinInt8,
Int16: math.MinInt16,
Int32: math.MinInt32,
Int64: math.MinInt64,
Uint: math.MaxUint32,
Uint8: math.MaxUint8,
Uint16: math.MaxUint16,
Uint32: math.MaxUint32,
Uint64: math.MaxUint64,
Float32: 1.5,
Float64: math.MaxFloat64,
Ptr: NamedStrPtr(&str),
}
var namedPrimitiveTypesString = "{" +
`"String":"test",` +
`"Bool":true,` +
`"Int":` + fmt.Sprint(math.MinInt32) + `,` +
`"Int8":` + fmt.Sprint(math.MinInt8) + `,` +
`"Int16":` + fmt.Sprint(math.MinInt16) + `,` +
`"Int32":` + fmt.Sprint(math.MinInt32) + `,` +
`"Int64":` + fmt.Sprint(int64(math.MinInt64)) + `,` +
`"Uint":` + fmt.Sprint(math.MaxUint32) + `,` +
`"Uint8":` + fmt.Sprint(math.MaxUint8) + `,` +
`"Uint16":` + fmt.Sprint(math.MaxUint16) + `,` +
`"Uint32":` + fmt.Sprint(math.MaxUint32) + `,` +
`"Uint64":` + fmt.Sprint(uint64(math.MaxUint64)) + `,` +
`"Float32":` + fmt.Sprint(1.5) + `,` +
`"Float64":` + fmt.Sprint(math.MaxFloat64) + `,` +
`"Ptr":"bla",` +
`"PtrNil":null` +
"}"
type SubStruct struct {
Value string
Value2 string
unexpored bool
}
type SubP struct {
V string
}
type SubStructAlias SubStruct
type Structs struct {
SubStruct
*SubP
Value2 int
Sub1 SubStruct `json:"substruct"`
Sub2 *SubStruct
SubNil *SubStruct
SubSlice []SubStruct
SubSliceNil []SubStruct
SubPtrSlice []*SubStruct
SubPtrSliceNil []*SubStruct
SubA1 SubStructAlias
SubA2 *SubStructAlias
Anonymous struct {
V string
I int
}
Anonymous1 *struct {
V string
}
AnonymousSlice []struct{ V int }
AnonymousPtrSlice []*struct{ V int }
Slice []string
unexported bool
}
var structsValue = Structs{
SubStruct: SubStruct{Value: "test"},
SubP: &SubP{V: "subp"},
Value2: 5,
Sub1: SubStruct{Value: "test1", Value2: "v"},
Sub2: &SubStruct{Value: "test2", Value2: "v2"},
SubSlice: []SubStruct{
{Value: "s1"},
{Value: "s2"},
},
SubPtrSlice: []*SubStruct{
{Value: "p1"},
{Value: "p2"},
},
SubA1: SubStructAlias{Value: "test3", Value2: "v3"},
SubA2: &SubStructAlias{Value: "test4", Value2: "v4"},
Anonymous: struct {
V string
I int
}{V: "bla", I: 5},
Anonymous1: &struct {
V string
}{V: "bla1"},
AnonymousSlice: []struct{ V int }{{1}, {2}},
AnonymousPtrSlice: []*struct{ V int }{{3}, {4}},
Slice: []string{"test5", "test6"},
}
var structsString = "{" +
`"Value2":5,` +
`"substruct":{"Value":"test1","Value2":"v"},` +
`"Sub2":{"Value":"test2","Value2":"v2"},` +
`"SubNil":null,` +
`"SubSlice":[{"Value":"s1","Value2":""},{"Value":"s2","Value2":""}],` +
`"SubSliceNil":null,` +
`"SubPtrSlice":[{"Value":"p1","Value2":""},{"Value":"p2","Value2":""}],` +
`"SubPtrSliceNil":null,` +
`"SubA1":{"Value":"test3","Value2":"v3"},` +
`"SubA2":{"Value":"test4","Value2":"v4"},` +
`"Anonymous":{"V":"bla","I":5},` +
`"Anonymous1":{"V":"bla1"},` +
`"AnonymousSlice":[{"V":1},{"V":2}],` +
`"AnonymousPtrSlice":[{"V":3},{"V":4}],` +
`"Slice":["test5","test6"],` +
// Embedded fields go last.
`"V":"subp",` +
`"Value":"test"` +
"}"
type OmitEmpty struct {
// NOTE: first field is empty to test comma printing.
StrE, StrNE string `json:",omitempty"`
PtrE, PtrNE *string `json:",omitempty"`
IntNE int `json:"intField,omitempty"`
IntE int `json:",omitempty"`
// NOTE: omitempty has no effect on non-pointer struct fields.
SubE, SubNE SubStruct `json:",omitempty"`
SubPE, SubPNE *SubStruct `json:",omitempty"`
}
var omitEmptyValue = OmitEmpty{
StrNE: "str",
PtrNE: &str,
IntNE: 6,
SubNE: SubStruct{Value: "1", Value2: "2"},
SubPNE: &SubStruct{Value: "3", Value2: "4"},
}
var omitEmptyString = "{" +
`"StrNE":"str",` +
`"PtrNE":"bla",` +
`"intField":6,` +
`"SubE":{"Value":"","Value2":""},` +
`"SubNE":{"Value":"1","Value2":"2"},` +
`"SubPNE":{"Value":"3","Value2":"4"}` +
"}"
type Opts struct {
StrNull opt.String
StrEmpty opt.String
Str opt.String
StrOmitempty opt.String `json:",omitempty"`
IntNull opt.Int
IntZero opt.Int
Int opt.Int
}
var optsValue = Opts{
StrEmpty: opt.OString(""),
Str: opt.OString("test"),
IntZero: opt.OInt(0),
Int: opt.OInt(5),
}
var optsString = `{` +
`"StrNull":null,` +
`"StrEmpty":"",` +
`"Str":"test",` +
`"IntNull":null,` +
`"IntZero":0,` +
`"Int":5` +
`}`
type Raw struct {
Field easyjson.RawMessage
Field2 string
}
var rawValue = Raw{
Field: []byte(`{"a" : "b"}`),
Field2: "test",
}
var rawString = `{` +
`"Field":{"a" : "b"},` +
`"Field2":"test"` +
`}`
type StdMarshaler struct {
T time.Time
IP net.IP
}
var stdMarshalerValue = StdMarshaler{
T: time.Date(2016, 01, 02, 14, 15, 10, 0, time.UTC),
IP: net.IPv4(192, 168, 0, 1),
}
var stdMarshalerString = `{` +
`"T":"2016-01-02T14:15:10Z",` +
`"IP":"192.168.0.1"` +
`}`
type UserMarshaler struct {
V vMarshaler
T tMarshaler
}
type vMarshaler net.IP
func (v vMarshaler) MarshalJSON() ([]byte, error) {
return []byte(`"0::0"`), nil
}
func (v *vMarshaler) UnmarshalJSON([]byte) error {
*v = vMarshaler(net.IPv6zero)
return nil
}
type tMarshaler net.IP
func (v tMarshaler) MarshalText() ([]byte, error) {
return []byte(`[0::0]`), nil
}
func (v *tMarshaler) UnmarshalText([]byte) error {
*v = tMarshaler(net.IPv6zero)
return nil
}
var userMarshalerValue = UserMarshaler{
V: vMarshaler(net.IPv6zero),
T: tMarshaler(net.IPv6zero),
}
var userMarshalerString = `{` +
`"V":"0::0",` +
`"T":"[0::0]"` +
`}`
type unexportedStruct struct {
Value string
}
var unexportedStructValue = unexportedStruct{"test"}
var unexportedStructString = `{"Value":"test"}`
type ExcludedField struct {
Process bool `json:"process"`
DoNotProcess bool `json:"-"`
DoNotProcess1 bool `json:"-"`
}
var excludedFieldValue = ExcludedField{
Process: true,
DoNotProcess: false,
DoNotProcess1: false,
}
var excludedFieldString = `{"process":true}`
type Slices struct {
ByteSlice []byte
EmptyByteSlice []byte
NilByteSlice []byte
IntSlice []int
EmptyIntSlice []int
NilIntSlice []int
}
var sliceValue = Slices{
ByteSlice: []byte("abc"),
EmptyByteSlice: []byte{},
NilByteSlice: []byte(nil),
IntSlice: []int{1, 2, 3, 4, 5},
EmptyIntSlice: []int{},
NilIntSlice: []int(nil),
}
var sliceString = `{` +
`"ByteSlice":"YWJj",` +
`"EmptyByteSlice":"",` +
`"NilByteSlice":null,` +
`"IntSlice":[1,2,3,4,5],` +
`"EmptyIntSlice":[],` +
`"NilIntSlice":null` +
`}`
type Arrays struct {
ByteArray [3]byte
EmptyByteArray [0]byte
IntArray [5]int
EmptyIntArray [0]int
}
var arrayValue = Arrays{
ByteArray: [3]byte{'a', 'b', 'c'},
EmptyByteArray: [0]byte{},
IntArray: [5]int{1, 2, 3, 4, 5},
EmptyIntArray: [0]int{},
}
var arrayString = `{` +
`"ByteArray":"YWJj",` +
`"EmptyByteArray":"",` +
`"IntArray":[1,2,3,4,5],` +
`"EmptyIntArray":[]` +
`}`
var arrayOverflowString = `{` +
`"ByteArray":"YWJjbnNk",` +
`"EmptyByteArray":"YWJj",` +
`"IntArray":[1,2,3,4,5,6],` +
`"EmptyIntArray":[7,8]` +
`}`
var arrayUnderflowValue = Arrays{
ByteArray: [3]byte{'x', 0, 0},
EmptyByteArray: [0]byte{},
IntArray: [5]int{1, 2, 0, 0, 0},
EmptyIntArray: [0]int{},
}
var arrayUnderflowString = `{` +
`"ByteArray":"eA==",` +
`"IntArray":[1,2]` +
`}`
type Str string
type Maps struct {
Map map[string]string
InterfaceMap map[string]interface{}
NilMap map[string]string
CustomMap map[Str]Str
}
var mapsValue = Maps{
Map: map[string]string{"A": "b"}, // only one item since map iteration is randomized
InterfaceMap: map[string]interface{}{"G": float64(1)},
CustomMap: map[Str]Str{"c": "d"},
}
var mapsString = `{` +
`"Map":{"A":"b"},` +
`"InterfaceMap":{"G":1},` +
`"NilMap":null,` +
`"CustomMap":{"c":"d"}` +
`}`
type NamedSlice []Str
type NamedMap map[Str]Str
type DeepNest struct {
SliceMap map[Str][]Str
SliceMap1 map[Str][]Str
SliceMap2 map[Str][]Str
NamedSliceMap map[Str]NamedSlice
NamedMapMap map[Str]NamedMap
MapSlice []map[Str]Str
NamedSliceSlice []NamedSlice
NamedMapSlice []NamedMap
NamedStringSlice []NamedString
}
var deepNestValue = DeepNest{
SliceMap: map[Str][]Str{
"testSliceMap": []Str{
"0",
"1",
},
},
SliceMap1: map[Str][]Str{
"testSliceMap1": []Str(nil),
},
SliceMap2: map[Str][]Str{
"testSliceMap2": []Str{},
},
NamedSliceMap: map[Str]NamedSlice{
"testNamedSliceMap": NamedSlice{
"2",
"3",
},
},
NamedMapMap: map[Str]NamedMap{
"testNamedMapMap": NamedMap{
"key1": "value1",
},
},
MapSlice: []map[Str]Str{
map[Str]Str{
"testMapSlice": "someValue",
},
},
NamedSliceSlice: []NamedSlice{
NamedSlice{
"someValue1",
"someValue2",
},
NamedSlice{
"someValue3",
"someValue4",
},
},
NamedMapSlice: []NamedMap{
NamedMap{
"key2": "value2",
},
NamedMap{
"key3": "value3",
},
},
NamedStringSlice: []NamedString{
"value4", "value5",
},
}
var deepNestString = `{` +
`"SliceMap":{` +
`"testSliceMap":["0","1"]` +
`},` +
`"SliceMap1":{` +
`"testSliceMap1":null` +
`},` +
`"SliceMap2":{` +
`"testSliceMap2":[]` +
`},` +
`"NamedSliceMap":{` +
`"testNamedSliceMap":["2","3"]` +
`},` +
`"NamedMapMap":{` +
`"testNamedMapMap":{"key1":"value1"}` +
`},` +
`"MapSlice":[` +
`{"testMapSlice":"someValue"}` +
`],` +
`"NamedSliceSlice":[` +
`["someValue1","someValue2"],` +
`["someValue3","someValue4"]` +
`],` +
`"NamedMapSlice":[` +
`{"key2":"value2"},` +
`{"key3":"value3"}` +
`],` +
`"NamedStringSlice":["value4","value5"]` +
`}`
//easyjson:json
type Ints []int
var IntsValue = Ints{1, 2, 3, 4, 5}
var IntsString = `[1,2,3,4,5]`
//easyjson:json
type MapStringString map[string]string
var mapStringStringValue = MapStringString{"a": "b"}
var mapStringStringString = `{"a":"b"}`
type RequiredOptionalStruct struct {
FirstName string `json:"first_name,required"`
Lastname string `json:"last_name"`
}
//easyjson:json
type EncodingFlagsTestMap struct {
F map[string]string
}
//easyjson:json
type EncodingFlagsTestSlice struct {
F []string
}
type StructWithInterface struct {
Field1 int `json:"f1"`
Field2 interface{} `json:"f2"`
Field3 string `json:"f3"`
}
type EmbeddedStruct struct {
Field1 int `json:"f1"`
Field2 string `json:"f2"`
}
var structWithInterfaceString = `{"f1":1,"f2":{"f1":11,"f2":"22"},"f3":"3"}`
var structWithInterfaceValueFilled = StructWithInterface{1, &EmbeddedStruct{11, "22"}, "3"}

23
vendor/github.com/mailru/easyjson/tests/errors.go generated vendored Normal file
View file

@ -0,0 +1,23 @@
package tests
//easyjson:json
type ErrorIntSlice []int
//easyjson:json
type ErrorBoolSlice []bool
//easyjson:json
type ErrorUintSlice []uint
//easyjson:json
type ErrorStruct struct {
Int int `json:"int"`
String string `json:"string"`
Slice []int `json:"slice"`
IntSlice []int `json:"int_slice"`
}
type ErrorNestedStruct struct {
ErrorStruct ErrorStruct `json:"error_struct"`
Int int `json:"int"`
}

243
vendor/github.com/mailru/easyjson/tests/errors_test.go generated vendored Normal file
View file

@ -0,0 +1,243 @@
package tests
import (
"testing"
"github.com/mailru/easyjson/jlexer"
)
func TestMultipleErrorsInt(t *testing.T) {
for i, test := range []struct {
Data []byte
Offsets []int
}{
{
Data: []byte(`[1, 2, 3, "4", "5"]`),
Offsets: []int{10, 15},
},
{
Data: []byte(`[1, {"2":"3"}, 3, "4"]`),
Offsets: []int{4, 18},
},
{
Data: []byte(`[1, "2", "3", "4", "5", "6"]`),
Offsets: []int{4, 9, 14, 19, 24},
},
{
Data: []byte(`[1, 2, 3, 4, "5"]`),
Offsets: []int{13},
},
{
Data: []byte(`[{"1": "2"}]`),
Offsets: []int{1},
},
} {
l := jlexer.Lexer{
Data: test.Data,
UseMultipleErrors: true,
}
var v ErrorIntSlice
v.UnmarshalEasyJSON(&l)
errors := l.GetNonFatalErrors()
if len(errors) != len(test.Offsets) {
t.Errorf("[%d] TestMultipleErrorsInt(): errornum: want: %d, got %d", i, len(test.Offsets), len(errors))
return
}
for ii, e := range errors {
if e.Offset != test.Offsets[ii] {
t.Errorf("[%d] TestMultipleErrorsInt(): offset[%d]: want %d, got %d", i, ii, test.Offsets[ii], e.Offset)
}
}
}
}
func TestMultipleErrorsBool(t *testing.T) {
for i, test := range []struct {
Data []byte
Offsets []int
}{
{
Data: []byte(`[true, false, true, false]`),
},
{
Data: []byte(`["test", "value", "lol", "1"]`),
Offsets: []int{1, 9, 18, 25},
},
{
Data: []byte(`[true, 42, {"a":"b", "c":"d"}, false]`),
Offsets: []int{7, 11},
},
} {
l := jlexer.Lexer{
Data: test.Data,
UseMultipleErrors: true,
}
var v ErrorBoolSlice
v.UnmarshalEasyJSON(&l)
errors := l.GetNonFatalErrors()
if len(errors) != len(test.Offsets) {
t.Errorf("[%d] TestMultipleErrorsBool(): errornum: want: %d, got %d", i, len(test.Offsets), len(errors))
return
}
for ii, e := range errors {
if e.Offset != test.Offsets[ii] {
t.Errorf("[%d] TestMultipleErrorsBool(): offset[%d]: want %d, got %d", i, ii, test.Offsets[ii], e.Offset)
}
}
}
}
func TestMultipleErrorsUint(t *testing.T) {
for i, test := range []struct {
Data []byte
Offsets []int
}{
{
Data: []byte(`[42, 42, 42]`),
},
{
Data: []byte(`[17, "42", 32]`),
Offsets: []int{5},
},
{
Data: []byte(`["zz", "zz"]`),
Offsets: []int{1, 7},
},
{
Data: []byte(`[{}, 42]`),
Offsets: []int{1},
},
} {
l := jlexer.Lexer{
Data: test.Data,
UseMultipleErrors: true,
}
var v ErrorUintSlice
v.UnmarshalEasyJSON(&l)
errors := l.GetNonFatalErrors()
if len(errors) != len(test.Offsets) {
t.Errorf("[%d] TestMultipleErrorsUint(): errornum: want: %d, got %d", i, len(test.Offsets), len(errors))
return
}
for ii, e := range errors {
if e.Offset != test.Offsets[ii] {
t.Errorf("[%d] TestMultipleErrorsUint(): offset[%d]: want %d, got %d", i, ii, test.Offsets[ii], e.Offset)
}
}
}
}
func TestMultipleErrorsStruct(t *testing.T) {
for i, test := range []struct {
Data []byte
Offsets []int
}{
{
Data: []byte(`{"string": "test", "slice":[42, 42, 42], "int_slice":[1, 2, 3]}`),
},
{
Data: []byte(`{"string": {"test": "test"}, "slice":[42, 42, 42], "int_slice":["1", 2, 3]}`),
Offsets: []int{11, 64},
},
{
Data: []byte(`{"slice": [42, 42], "string": {"test": "test"}, "int_slice":["1", "2", 3]}`),
Offsets: []int{30, 61, 66},
},
{
Data: []byte(`{"string": "test", "slice": {}}`),
Offsets: []int{28},
},
{
Data: []byte(`{"slice":5, "string" : "test"}`),
Offsets: []int{9},
},
{
Data: []byte(`{"slice" : "test", "string" : "test"}`),
Offsets: []int{11},
},
{
Data: []byte(`{"slice": "", "string" : {}, "int":{}}`),
Offsets: []int{10, 25, 35},
},
} {
l := jlexer.Lexer{
Data: test.Data,
UseMultipleErrors: true,
}
var v ErrorStruct
v.UnmarshalEasyJSON(&l)
errors := l.GetNonFatalErrors()
if len(errors) != len(test.Offsets) {
t.Errorf("[%d] TestMultipleErrorsStruct(): errornum: want: %d, got %d", i, len(test.Offsets), len(errors))
return
}
for ii, e := range errors {
if e.Offset != test.Offsets[ii] {
t.Errorf("[%d] TestMultipleErrorsStruct(): offset[%d]: want %d, got %d", i, ii, test.Offsets[ii], e.Offset)
}
}
}
}
func TestMultipleErrorsNestedStruct(t *testing.T) {
for i, test := range []struct {
Data []byte
Offsets []int
}{
{
Data: []byte(`{"error_struct":{}}`),
},
{
Data: []byte(`{"error_struct":5}`),
Offsets: []int{16},
},
{
Data: []byte(`{"error_struct":[]}`),
Offsets: []int{16},
},
{
Data: []byte(`{"error_struct":{"int":{}}}`),
Offsets: []int{23},
},
{
Data: []byte(`{"error_struct":{"int_slice":{}}, "int":4}`),
Offsets: []int{29},
},
{
Data: []byte(`{"error_struct":{"int_slice":["1", 2, "3"]}, "int":[]}`),
Offsets: []int{30, 38, 51},
},
} {
l := jlexer.Lexer{
Data: test.Data,
UseMultipleErrors: true,
}
var v ErrorNestedStruct
v.UnmarshalEasyJSON(&l)
errors := l.GetNonFatalErrors()
if len(errors) != len(test.Offsets) {
t.Errorf("[%d] TestMultipleErrorsNestedStruct(): errornum: want: %d, got %d", i, len(test.Offsets), len(errors))
return
}
for ii, e := range errors {
if e.Offset != test.Offsets[ii] {
t.Errorf("[%d] TestMultipleErrorsNestedStruct(): offset[%d]: want %d, got %d", i, ii, test.Offsets[ii], e.Offset)
}
}
}
}

22
vendor/github.com/mailru/easyjson/tests/named_type.go generated vendored Normal file
View file

@ -0,0 +1,22 @@
package tests
//easyjson:json
type NamedType struct {
Inner struct {
// easyjson is mistakenly naming the type of this field 'tests.MyString' in the generated output
// something about a named type inside an anonmymous type is triggering this bug
Field MyString `tag:"value"`
Field2 int "tag:\"value with ` in it\""
}
}
type MyString string
var namedTypeValue NamedType
func init() {
namedTypeValue.Inner.Field = "test"
namedTypeValue.Inner.Field2 = 123
}
var namedTypeValueString = `{"Inner":{"Field":"test","Field2":123}}`

25
vendor/github.com/mailru/easyjson/tests/nested_easy.go generated vendored Normal file
View file

@ -0,0 +1,25 @@
package tests
import (
"github.com/mailru/easyjson"
"github.com/mailru/easyjson/jwriter"
)
//easyjson:json
type NestedInterfaces struct {
Value interface{}
Slice []interface{}
Map map[string]interface{}
}
type NestedEasyMarshaler struct {
EasilyMarshaled bool
}
var _ easyjson.Marshaler = &NestedEasyMarshaler{}
func (i *NestedEasyMarshaler) MarshalEasyJSON(w *jwriter.Writer) {
// We use this method only to indicate that easyjson.Marshaler
// interface was really used while encoding.
i.EasilyMarshaled = true
}

3
vendor/github.com/mailru/easyjson/tests/nothing.go generated vendored Normal file
View file

@ -0,0 +1,3 @@
package tests
// No structs in this file

12
vendor/github.com/mailru/easyjson/tests/omitempty.go generated vendored Normal file
View file

@ -0,0 +1,12 @@
package tests
//easyjson:json
type OmitEmptyDefault struct {
Field string
Str string
Str1 string `json:"s,!omitempty"`
Str2 string `json:",!omitempty"`
}
var omitEmptyDefaultValue = OmitEmptyDefault{Field: "test"}
var omitEmptyDefaultString = `{"Field":"test","s":"","Str2":""}`

View file

@ -0,0 +1,28 @@
package tests
import (
"fmt"
"testing"
)
func TestRequiredField(t *testing.T) {
cases := []struct{ json, errorMessage string }{
{`{"first_name":"Foo", "last_name": "Bar"}`, ""},
{`{"last_name":"Bar"}`, "key 'first_name' is required"},
{"{}", "key 'first_name' is required"},
}
for _, tc := range cases {
var v RequiredOptionalStruct
err := v.UnmarshalJSON([]byte(tc.json))
if tc.errorMessage == "" {
if err != nil {
t.Errorf("%s. UnmarshalJSON didn`t expect error: %v", tc.json, err)
}
} else {
if fmt.Sprintf("%v", err) != tc.errorMessage {
t.Errorf("%s. UnmarshalJSON expected error: %v. got: %v", tc.json, tc.errorMessage, err)
}
}
}
}

10
vendor/github.com/mailru/easyjson/tests/snake.go generated vendored Normal file
View file

@ -0,0 +1,10 @@
package tests
//easyjson:json
type SnakeStruct struct {
WeirdHTTPStuff bool
CustomNamedField string `json:"cUsToM"`
}
var snakeStructValue SnakeStruct
var snakeStructString = `{"weird_http_stuff":false,"cUsToM":""}`