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:
parent
e08fb277fa
commit
6e3be7f3d5
8538 changed files with 2537051 additions and 81115 deletions
4
vendor/github.com/mailru/easyjson/.gitignore
generated
vendored
Normal file
4
vendor/github.com/mailru/easyjson/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
.root
|
||||
*_easyjson.go
|
||||
*.iml
|
||||
.idea
|
8
vendor/github.com/mailru/easyjson/.travis.yml
generated
vendored
Normal file
8
vendor/github.com/mailru/easyjson/.travis.yml
generated
vendored
Normal 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
7
vendor/github.com/mailru/easyjson/LICENSE
generated
vendored
Normal 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
54
vendor/github.com/mailru/easyjson/Makefile
generated
vendored
Normal 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
329
vendor/github.com/mailru/easyjson/README.md
generated
vendored
Normal file
|
@ -0,0 +1,329 @@
|
|||
# easyjson [](https://travis-ci.org/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
|
279
vendor/github.com/mailru/easyjson/benchmark/codec_test.go
generated
vendored
Normal file
279
vendor/github.com/mailru/easyjson/benchmark/codec_test.go
generated
vendored
Normal 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
148
vendor/github.com/mailru/easyjson/benchmark/data.go
generated
vendored
Normal 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
6914
vendor/github.com/mailru/easyjson/benchmark/data_codec.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
6723
vendor/github.com/mailru/easyjson/benchmark/data_ffjson.go
generated
vendored
Normal file
6723
vendor/github.com/mailru/easyjson/benchmark/data_ffjson.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
350
vendor/github.com/mailru/easyjson/benchmark/data_var.go
generated
vendored
Normal file
350
vendor/github.com/mailru/easyjson/benchmark/data_var.go
generated
vendored
Normal 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,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
118
vendor/github.com/mailru/easyjson/benchmark/default_test.go
generated
vendored
Normal file
118
vendor/github.com/mailru/easyjson/benchmark/default_test.go
generated
vendored
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
11
vendor/github.com/mailru/easyjson/benchmark/dummy_test.go
generated
vendored
Normal file
11
vendor/github.com/mailru/easyjson/benchmark/dummy_test.go
generated
vendored
Normal 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) {}
|
184
vendor/github.com/mailru/easyjson/benchmark/easyjson_test.go
generated
vendored
Normal file
184
vendor/github.com/mailru/easyjson/benchmark/easyjson_test.go
generated
vendored
Normal 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)
|
||||
}
|
415
vendor/github.com/mailru/easyjson/benchmark/example.json
generated
vendored
Normal file
415
vendor/github.com/mailru/easyjson/benchmark/example.json
generated
vendored
Normal 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"
|
||||
}
|
||||
}
|
190
vendor/github.com/mailru/easyjson/benchmark/ffjson_test.go
generated
vendored
Normal file
190
vendor/github.com/mailru/easyjson/benchmark/ffjson_test.go
generated
vendored
Normal 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
7
vendor/github.com/mailru/easyjson/benchmark/ujson.sh
generated
vendored
Executable 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)'
|
184
vendor/github.com/mailru/easyjson/bootstrap/bootstrap.go
generated
vendored
Normal file
184
vendor/github.com/mailru/easyjson/bootstrap/bootstrap.go
generated
vendored
Normal 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
270
vendor/github.com/mailru/easyjson/buffer/pool.go
generated
vendored
Normal 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
107
vendor/github.com/mailru/easyjson/buffer/pool_test.go
generated
vendored
Normal 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
99
vendor/github.com/mailru/easyjson/easyjson/main.go
generated
vendored
Normal 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
471
vendor/github.com/mailru/easyjson/gen/decoder.go
generated
vendored
Normal 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
358
vendor/github.com/mailru/easyjson/gen/encoder.go
generated
vendored
Normal 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
449
vendor/github.com/mailru/easyjson/gen/generator.go
generated
vendored
Normal 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()
|
||||
}
|
65
vendor/github.com/mailru/easyjson/gen/generator_test.go
generated
vendored
Normal file
65
vendor/github.com/mailru/easyjson/gen/generator_test.go
generated
vendored
Normal 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
78
vendor/github.com/mailru/easyjson/helpers.go
generated
vendored
Normal 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
24
vendor/github.com/mailru/easyjson/jlexer/bytestostr.go
generated
vendored
Normal 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))
|
||||
}
|
13
vendor/github.com/mailru/easyjson/jlexer/bytestostr_nounsafe.go
generated
vendored
Normal file
13
vendor/github.com/mailru/easyjson/jlexer/bytestostr_nounsafe.go
generated
vendored
Normal 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
15
vendor/github.com/mailru/easyjson/jlexer/error.go
generated
vendored
Normal 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
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
251
vendor/github.com/mailru/easyjson/jlexer/lexer_test.go
generated
vendored
Normal 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
328
vendor/github.com/mailru/easyjson/jwriter/writer.go
generated
vendored
Normal 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('"')
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Bool.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Bool.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Float32.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Float32.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Float64.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Float64.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Int.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Int.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Int16.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Int16.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Int32.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Int32.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Int64.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Int64.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Int8.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Int8.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_String.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_String.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Uint.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Uint.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Uint16.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Uint16.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Uint32.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Uint32.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Uint64.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Uint64.go
generated
vendored
Normal 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)
|
||||
}
|
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Uint8.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/opt/gotemplate_Uint8.go
generated
vendored
Normal 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
80
vendor/github.com/mailru/easyjson/opt/optional/opt.go
generated
vendored
Normal 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
22
vendor/github.com/mailru/easyjson/opt/opts.go
generated
vendored
Normal 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
91
vendor/github.com/mailru/easyjson/parser/parser.go
generated
vendored
Normal 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
|
||||
}
|
33
vendor/github.com/mailru/easyjson/parser/parser_unix.go
generated
vendored
Normal file
33
vendor/github.com/mailru/easyjson/parser/parser_unix.go
generated
vendored
Normal 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)
|
||||
}
|
37
vendor/github.com/mailru/easyjson/parser/parser_windows.go
generated
vendored
Normal file
37
vendor/github.com/mailru/easyjson/parser/parser_windows.go
generated
vendored
Normal 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
45
vendor/github.com/mailru/easyjson/raw.go
generated
vendored
Normal 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
222
vendor/github.com/mailru/easyjson/tests/basic_test.go
generated
vendored
Normal 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
694
vendor/github.com/mailru/easyjson/tests/data.go
generated
vendored
Normal 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
23
vendor/github.com/mailru/easyjson/tests/errors.go
generated
vendored
Normal 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
243
vendor/github.com/mailru/easyjson/tests/errors_test.go
generated
vendored
Normal 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
22
vendor/github.com/mailru/easyjson/tests/named_type.go
generated
vendored
Normal 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
25
vendor/github.com/mailru/easyjson/tests/nested_easy.go
generated
vendored
Normal 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
3
vendor/github.com/mailru/easyjson/tests/nothing.go
generated
vendored
Normal 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
12
vendor/github.com/mailru/easyjson/tests/omitempty.go
generated
vendored
Normal 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":""}`
|
28
vendor/github.com/mailru/easyjson/tests/required_test.go
generated
vendored
Normal file
28
vendor/github.com/mailru/easyjson/tests/required_test.go
generated
vendored
Normal 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
10
vendor/github.com/mailru/easyjson/tests/snake.go
generated
vendored
Normal 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":""}`
|
Loading…
Add table
Add a link
Reference in a new issue