mirror of
https://github.com/kubernetes-sigs/descheduler.git
synced 2026-01-28 14:41:10 +01:00
Update vendor dependencies.
This commit is contained in:
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.
|
||||
50
vendor/github.com/mailru/easyjson/Makefile
generated
vendored
Normal file
50
vendor/github.com/mailru/easyjson/Makefile
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
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/bin/easyjson -all .root/src/$(PKG)/tests/data.go
|
||||
.root/bin/easyjson -all .root/src/$(PKG)/tests/nothing.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
|
||||
|
||||
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
|
||||
193
vendor/github.com/mailru/easyjson/README.md
generated
vendored
Normal file
193
vendor/github.com/mailru/easyjson/README.md
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
# easyjson [](https://travis-ci.org/mailru/easyjson)
|
||||
|
||||
easyjson allows to (un-)marshal JSON golang structs without the use of reflection by generating marshaller code.
|
||||
|
||||
One of the aims of the library is to keep generated code simple enough so that it can be easily optimized or fixed. Another goal is to provide users with ability to customize the generated code not available in 'encoding/json', such as generating snake_case names or enabling 'omitempty' behavior by default.
|
||||
|
||||
## usage
|
||||
```
|
||||
go get github.com/mailru/easyjson/...
|
||||
easyjson -all <file>.go
|
||||
```
|
||||
|
||||
This will generate `<file>_easyjson.go` with marshaller/unmarshaller methods for structs. `GOPATH` variable needs to be set up correctly, since the generation invokes a `go run` on a temporary file (this is a really convenient approach to code generation borrowed from https://github.com/pquerna/ffjson).
|
||||
|
||||
## options
|
||||
```
|
||||
Usage of .root/bin/easyjson:
|
||||
-all
|
||||
generate un-/marshallers 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 methods
|
||||
-noformat
|
||||
do not run 'gofmt -w' on output file
|
||||
-omit_empty
|
||||
omit empty fields by default
|
||||
-snake_case
|
||||
use snake_case names instead of CamelCase by default
|
||||
-stubs
|
||||
only generate stubs for marshallers/unmarshallers methods
|
||||
```
|
||||
|
||||
Using `-all` will generate (un-)marshallers for all structs in the file. By default, structs need to have a line beginning with `easyjson:json` in their docstring, e.g.:
|
||||
```
|
||||
//easyjson:json
|
||||
struct A{}
|
||||
```
|
||||
|
||||
`-snake_case` tells easyjson to generate snake\_case field names by default (unless explicitly overriden by a field tag). The CamelCase to snake\_case conversion algorithm should work in most cases (e.g. HTTPVersion will be converted to http_version). There can be names like JSONHTTPRPC where the conversion will return an unexpected result (jsonhttprpc without underscores), but such names require a dictionary to do the conversion and may be ambiguous.
|
||||
|
||||
`-build_tags` will add corresponding build tag line for the generated file.
|
||||
## marshaller/unmarshaller interfaces
|
||||
|
||||
easyjson generates MarshalJSON/UnmarshalJSON methods that are compatible with interfaces from 'encoding/json'. They are usable with 'json.Marshal' and 'json.Unmarshal' functions, however actually using those will result in significantly worse performance compared to custom interfaces.
|
||||
|
||||
`MarshalEasyJSON` / `UnmarshalEasyJSON` methods are generated for faster parsing using custom Lexer/Writer structs (`jlexer.Lexer` and `jwriter.Writer`). The method signature is defined in `easyjson.Marshaler` / `easyjson.Unmarshaler` interfaces. These interfaces allow to avoid using any unnecessary reflection or type assertions during parsing. Functions can be used manually or with `easyjson.Marshal<...>` and `easyjson.Unmarshal<...>` helper methods.
|
||||
|
||||
`jwriter.Writer` struct in addition to function for returning the data as a single slice also has methods to return the size and to send the data to an `io.Writer`. This is aimed at a typical HTTP use-case, when you want to know the `Content-Length` before actually starting to send the data.
|
||||
|
||||
There are helpers in the top-level package for marhsaling/unmarshaling the data using custom interfaces to and from writers, including a helper for `http.ResponseWriter`.
|
||||
|
||||
## custom types
|
||||
If `easyjson.Marshaler` / `easyjson.Unmarshaler` interfaces are implemented by a type involved in JSON parsing, the type will be marshaled/unmarshaled using these methods. `easyjson.Optional` interface allows for a custom type to integrate with 'omitempty' logic.
|
||||
|
||||
As an example, easyjson includes an `easyjson.RawMessage` analogous to `json.RawMessage`.
|
||||
|
||||
Also, there are 'optional' wrappers for primitive types in `easyjson/opt` package. These are useful in the case when it is necessary to distinguish between missing and default value for the type. Wrappers allow to avoid pointers and extra heap allocations in such cases.
|
||||
|
||||
## memory pooling
|
||||
|
||||
The library uses a custom buffer which allocates data in increasing chunks (128-32768 bytes). Chunks of 512 bytes and larger are reused with the help of `sync.Pool`. The maximum size of a chunk is bounded to reduce redundancy in memory allocation and to make the chunks more reusable in the case of large buffer sizes.
|
||||
|
||||
The buffer code is in `easyjson/buffer` package the exact values can be tweaked by a `buffer.Init()` call before the first serialization.
|
||||
|
||||
## limitations
|
||||
* The library is at an early stage, there are likely to be some bugs and some features of 'encoding/json' may not be supported. Please report such cases, so that they may be fixed sooner.
|
||||
* Object keys are case-sensitive (unlike encodin/json). Case-insentive behavior will be implemented as an option (case-insensitive matching is slower).
|
||||
* Unsafe package is used by the code. While a non-unsafe version of easyjson can be made in the future, using unsafe package simplifies a lot of code by allowing no-copy []byte to string conversion within the library. This is used only during parsing and all the returned values are allocated properly.
|
||||
* Floats are currently formatted with default precision for 'strconv' package. It is obvious that it is not always the correct way to handle it, but there aren't enough use-cases for floats at hand to do anything better.
|
||||
* During parsing, parts of JSON that are skipped over are not syntactically validated more than required to skip matching parentheses.
|
||||
* No true streaming support for encoding/decoding. For many use-cases and protocols, data length is typically known on input and needs to be known before sending the data.
|
||||
|
||||
## benchmarks
|
||||
Most benchmarks were done using a sample 13kB JSON (9k if serialized back trimming the whitespace) from https://dev.twitter.com/rest/reference/get/search/tweets. The sample is very close to real-world data, quite structured and contains a variety of different types.
|
||||
|
||||
For small request benchmarks, an 80-byte portion of the regular sample was used.
|
||||
|
||||
For large request marshalling benchmarks, a struct containing 50 regular samples was used, making a ~500kB output JSON.
|
||||
|
||||
Benchmarks are available in the repository and are run on 'make'.
|
||||
|
||||
### easyjson vs. encoding/json
|
||||
|
||||
easyjson seems to be 5-6 times faster than the default json serialization for unmarshalling, 3-4 times faster for non-concurrent marshalling. Concurrent marshalling is 6-7x faster if marshalling to a writer.
|
||||
|
||||
### easyjson vs. ffjson
|
||||
|
||||
easyjson uses the same approach for code generation as ffjson, but a significantly different approach to lexing and generated code. This allows easyjson to be 2-3x faster for unmarshalling and 1.5-2x faster for non-concurrent unmarshalling.
|
||||
|
||||
ffjson seems to behave weird if used concurrently: for large request pooling hurts performance instead of boosting it, it also does not quite scale well. These issues are likely to be fixable and until that comparisons might vary from version to version a lot.
|
||||
|
||||
easyjson is similar in performance for small requests and 2-5x times faster for large ones if used with a writer.
|
||||
|
||||
### easyjson vs. go/codec
|
||||
|
||||
github.com/ugorji/go/codec library provides compile-time helpers for JSON generation. In this case, helpers are not exactly marshallers as they are encoding-independent.
|
||||
|
||||
easyjson is generally ~2x faster for non-concurrent benchmarks and about 3x faster for concurrent encoding (without marshalling to a writer). Unsafe option for generated helpers was used.
|
||||
|
||||
As an attempt to measure marshalling performance of 'go/codec' (as opposed to allocations/memcpy/writer interface invocations), a benchmark was done with resetting lenght 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 marshalling operations.
|
||||
|
||||
### easyjson vs 'ujson' python module
|
||||
ujson 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 seems to be slightly faster for unmarshalling (finally!) and 2-3x faster for marshalling.
|
||||
|
||||
### benchmark figures
|
||||
The data was measured on 4 February, 2016 using current ffjson and golang 1.6. Data for go/codec was added on 4 March 2016, benchmarked on the same machine.
|
||||
|
||||
#### Unmarshalling
|
||||
| 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
|
||||
|
||||
#### Marshalling, 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
|
||||
\* marshalling to a writer,
|
||||
\*\* using `ffjson.Pool()`,
|
||||
\*\*\* reusing output slice instead of resetting it to nil
|
||||
|
||||
#### Marshalling, 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
|
||||
\* marshalling 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
|
||||
}
|
||||
6911
vendor/github.com/mailru/easyjson/benchmark/data_codec.go
generated
vendored
Normal file
6911
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)'
|
||||
180
vendor/github.com/mailru/easyjson/bootstrap/bootstrap.go
generated
vendored
Normal file
180
vendor/github.com/mailru/easyjson/bootstrap/bootstrap.go
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
// 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"
|
||||
)
|
||||
|
||||
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, ")")
|
||||
}
|
||||
|
||||
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()")
|
||||
}
|
||||
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)
|
||||
}
|
||||
207
vendor/github.com/mailru/easyjson/buffer/pool.go
generated
vendored
Normal file
207
vendor/github.com/mailru/easyjson/buffer/pool.go
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
// 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.
|
||||
func (b *Buffer) BuildBytes() []byte {
|
||||
if len(b.bufs) == 0 {
|
||||
|
||||
ret := b.Buf
|
||||
b.toPool = nil
|
||||
b.Buf = nil
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
ret := make([]byte, 0, b.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
|
||||
}
|
||||
79
vendor/github.com/mailru/easyjson/buffer/pool_test.go
generated
vendored
Normal file
79
vendor/github.com/mailru/easyjson/buffer/pool_test.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
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))
|
||||
}
|
||||
}
|
||||
83
vendor/github.com/mailru/easyjson/easyjson/main.go
generated
vendored
Normal file
83
vendor/github.com/mailru/easyjson/easyjson/main.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"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 methods")
|
||||
var omitEmpty = flag.Bool("omit_empty", false, "omit empty fields by default")
|
||||
var allStructs = flag.Bool("all", false, "generate un-/marshallers 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 marshallers/unmarshallers methods")
|
||||
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")
|
||||
|
||||
func generate(fname string) (err error) {
|
||||
p := parser.Parser{AllStructs: *allStructs}
|
||||
if err := p.Parse(fname); err != nil {
|
||||
return fmt.Errorf("Error parsing %v: %v", fname, err)
|
||||
}
|
||||
|
||||
var outName string
|
||||
if s := strings.TrimSuffix(fname, ".go"); s == fname {
|
||||
return fmt.Errorf("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 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
385
vendor/github.com/mailru/easyjson/gen/decoder.go
generated
vendored
Normal file
385
vendor/github.com/mailru/easyjson/gen/decoder.go
generated
vendored
Normal file
@@ -0,0 +1,385 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"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
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
capacity := minSliceBytes / elem.Size()
|
||||
if capacity == 0 {
|
||||
capacity = 1
|
||||
}
|
||||
|
||||
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)+", 0, "+fmt.Sprint(capacity)+")")
|
||||
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+" var "+tmpVar+" "+g.getType(elem))
|
||||
|
||||
g.genTypeDecoder(elem, tmpVar, tags, indent+1)
|
||||
|
||||
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(']')")
|
||||
|
||||
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+" "+out+" = new("+g.getType(t.Elem())+")")
|
||||
|
||||
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+out+" = in.Interface()")
|
||||
|
||||
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:
|
||||
return g.genSliceDecoder(t)
|
||||
default:
|
||||
return g.genStructDecoder(t)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Generator) genSliceDecoder(t reflect.Type) error {
|
||||
if t.Kind() != reflect.Slice {
|
||||
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice type", t)
|
||||
}
|
||||
|
||||
fname := g.getDecoderName(t)
|
||||
typ := g.getType(t)
|
||||
|
||||
fmt.Fprintln(g.out, "func "+fname+"(in *jlexer.Lexer, out *"+typ+") {")
|
||||
err := g.genTypeDecoderNoCheck(t, "*out", fieldTags{}, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
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, " if in.IsNull() {")
|
||||
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('}')")
|
||||
|
||||
for _, f := range fs {
|
||||
g.genRequiredFieldCheck(t, f)
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, "}")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Generator) genStructUnmarshaller(t reflect.Type) error {
|
||||
if t.Kind() != reflect.Struct && t.Kind() != reflect.Slice {
|
||||
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice 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
|
||||
}
|
||||
313
vendor/github.com/mailru/easyjson/gen/encoder.go
generated
vendored
Normal file
313
vendor/github.com/mailru/easyjson/gen/encoder.go
generated
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"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
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
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+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 {")
|
||||
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+"out.Raw(json.Marshal("+in+"))")
|
||||
|
||||
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:
|
||||
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:
|
||||
return g.genSliceEncoder(t)
|
||||
default:
|
||||
return g.genStructEncoder(t)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Generator) genSliceEncoder(t reflect.Type) error {
|
||||
if t.Kind() != reflect.Slice {
|
||||
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice 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")
|
||||
}
|
||||
|
||||
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) genStructMarshaller(t reflect.Type) error {
|
||||
if t.Kind() != reflect.Struct && t.Kind() != reflect.Slice {
|
||||
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice 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
|
||||
}
|
||||
395
vendor/github.com/mailru/easyjson/gen/generator.go
generated
vendored
Normal file
395
vendor/github.com/mailru/easyjson/gen/generator.go
generated
vendored
Normal file
@@ -0,0 +1,395 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"io"
|
||||
"path"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const pkgWriter = "github.com/mailru/easyjson/jwriter"
|
||||
const pkgLexer = "github.com/mailru/easyjson/jlexer"
|
||||
|
||||
// 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 marshallers/unmarshallers.
|
||||
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 marshallers were requested for by user
|
||||
marshallers 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",
|
||||
"encoding/json": "json",
|
||||
},
|
||||
fieldNamer: DefaultFieldNamer{},
|
||||
marshallers: 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 functions 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 en-/decoding functions 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 (un-)marshallers and en-/decoding functions 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.marshallers[t] = true
|
||||
}
|
||||
|
||||
// printHeader prints package declaration and imports.
|
||||
func (g *Generator) printHeader() {
|
||||
if g.buildTags != "" {
|
||||
fmt.Println("// +build ", g.buildTags)
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Println("// AUTOGENERATED FILE: easyjson marshaller/unmarshallers.")
|
||||
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 g.imports {
|
||||
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(")")
|
||||
|
||||
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.marshallers[t] {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := g.genStructMarshaller(t); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.genStructUnmarshaller(t); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
g.printHeader()
|
||||
_, err := out.Write(g.out.Bytes())
|
||||
return err
|
||||
}
|
||||
|
||||
// pkgAlias creates and returns and import alias for a given package.
|
||||
func (g *Generator) pkgAlias(pkgPath string) string {
|
||||
if alias := g.imports[pkgPath]; alias != "" {
|
||||
return alias
|
||||
}
|
||||
|
||||
for i := 0; ; i++ {
|
||||
alias := 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.Map:
|
||||
return "map[" + g.getType(t.Key()) + "]" + g.getType(t.Elem())
|
||||
}
|
||||
}
|
||||
|
||||
if t.Name() == "" || t.PkgPath() == "" {
|
||||
return t.String()
|
||||
} else if t.PkgPath() == g.pkgPath {
|
||||
return t.Name()
|
||||
}
|
||||
// TODO: unnamed structs.
|
||||
return g.pkgAlias(t.PkgPath()) + "." + t.Name()
|
||||
}
|
||||
|
||||
// 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()
|
||||
}
|
||||
49
vendor/github.com/mailru/easyjson/gen/generator_test.go
generated
vendored
Normal file
49
vendor/github.com/mailru/easyjson/gen/generator_test.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
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()
|
||||
}
|
||||
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)
|
||||
}
|
||||
956
vendor/github.com/mailru/easyjson/jlexer/lexer.go
generated
vendored
Normal file
956
vendor/github.com/mailru/easyjson/jlexer/lexer.go
generated
vendored
Normal file
@@ -0,0 +1,956 @@
|
||||
// Package jlexer contains a JSON lexer implementation.
|
||||
//
|
||||
// It is expected that it is mostly used with generated parser code, so the interface is tuned
|
||||
// for a parser that knows what kind of data is expected.
|
||||
package jlexer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// tokenKind determines type of a token.
|
||||
type tokenKind byte
|
||||
|
||||
const (
|
||||
tokenUndef tokenKind = iota // No token.
|
||||
tokenDelim // Delimiter: one of '{', '}', '[' or ']'.
|
||||
tokenString // A string literal, e.g. "abc\u1234"
|
||||
tokenNumber // Number literal, e.g. 1.5e5
|
||||
tokenBool // Boolean literal: true or false.
|
||||
tokenNull // null keyword.
|
||||
)
|
||||
|
||||
// token describes a single token: type, position in the input and value.
|
||||
type token struct {
|
||||
kind tokenKind // Type of a token.
|
||||
|
||||
boolValue bool // Value if a boolean literal token.
|
||||
byteValue []byte // Raw value of a token.
|
||||
delimValue byte
|
||||
}
|
||||
|
||||
// Lexer is a JSON lexer: it iterates over JSON tokens in a byte slice.
|
||||
type Lexer struct {
|
||||
Data []byte // Input data given to the lexer.
|
||||
|
||||
start int // Start of the current token.
|
||||
pos int // Current unscanned position in the input stream.
|
||||
token token // Last scanned token, if token.kind != tokenUndef.
|
||||
|
||||
firstElement bool // Whether current element is the first in array or an object.
|
||||
wantSep byte // A comma or a colon character, which need to occur before a token.
|
||||
|
||||
err error // Error encountered during lexing, if any.
|
||||
}
|
||||
|
||||
// fetchToken scans the input for the next token.
|
||||
func (r *Lexer) fetchToken() {
|
||||
r.token.kind = tokenUndef
|
||||
r.start = r.pos
|
||||
|
||||
// Check if r.Data has r.pos element
|
||||
// If it doesn't, it mean corrupted input data
|
||||
if len(r.Data) < r.pos {
|
||||
r.errParse("Unexpected end of data")
|
||||
return
|
||||
}
|
||||
// Determine the type of a token by skipping whitespace and reading the
|
||||
// first character.
|
||||
for _, c := range r.Data[r.pos:] {
|
||||
switch c {
|
||||
case ':', ',':
|
||||
if r.wantSep == c {
|
||||
r.pos++
|
||||
r.start++
|
||||
r.wantSep = 0
|
||||
} else {
|
||||
r.errSyntax()
|
||||
}
|
||||
|
||||
case ' ', '\t', '\r', '\n':
|
||||
r.pos++
|
||||
r.start++
|
||||
|
||||
case '"':
|
||||
if r.wantSep != 0 {
|
||||
r.errSyntax()
|
||||
}
|
||||
|
||||
r.token.kind = tokenString
|
||||
r.fetchString()
|
||||
return
|
||||
|
||||
case '{', '[':
|
||||
if r.wantSep != 0 {
|
||||
r.errSyntax()
|
||||
}
|
||||
r.firstElement = true
|
||||
r.token.kind = tokenDelim
|
||||
r.token.delimValue = r.Data[r.pos]
|
||||
r.pos++
|
||||
return
|
||||
|
||||
case '}', ']':
|
||||
if !r.firstElement && (r.wantSep != ',') {
|
||||
r.errSyntax()
|
||||
}
|
||||
r.wantSep = 0
|
||||
r.token.kind = tokenDelim
|
||||
r.token.delimValue = r.Data[r.pos]
|
||||
r.pos++
|
||||
return
|
||||
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-':
|
||||
if r.wantSep != 0 {
|
||||
r.errSyntax()
|
||||
}
|
||||
r.token.kind = tokenNumber
|
||||
r.fetchNumber()
|
||||
return
|
||||
|
||||
case 'n':
|
||||
if r.wantSep != 0 {
|
||||
r.errSyntax()
|
||||
}
|
||||
|
||||
r.token.kind = tokenNull
|
||||
r.fetchNull()
|
||||
return
|
||||
|
||||
case 't':
|
||||
if r.wantSep != 0 {
|
||||
r.errSyntax()
|
||||
}
|
||||
|
||||
r.token.kind = tokenBool
|
||||
r.token.boolValue = true
|
||||
r.fetchTrue()
|
||||
return
|
||||
|
||||
case 'f':
|
||||
if r.wantSep != 0 {
|
||||
r.errSyntax()
|
||||
}
|
||||
|
||||
r.token.kind = tokenBool
|
||||
r.token.boolValue = false
|
||||
r.fetchFalse()
|
||||
return
|
||||
|
||||
default:
|
||||
r.errSyntax()
|
||||
return
|
||||
}
|
||||
}
|
||||
r.err = io.EOF
|
||||
return
|
||||
}
|
||||
|
||||
// isTokenEnd returns true if the char can follow a non-delimiter token
|
||||
func isTokenEnd(c byte) bool {
|
||||
return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '[' || c == ']' || c == '{' || c == '}' || c == ',' || c == ':'
|
||||
}
|
||||
|
||||
// fetchNull fetches and checks remaining bytes of null keyword.
|
||||
func (r *Lexer) fetchNull() {
|
||||
r.pos += 4
|
||||
if r.pos > len(r.Data) ||
|
||||
r.Data[r.pos-3] != 'u' ||
|
||||
r.Data[r.pos-2] != 'l' ||
|
||||
r.Data[r.pos-1] != 'l' ||
|
||||
(r.pos != len(r.Data) && !isTokenEnd(r.Data[r.pos])) {
|
||||
|
||||
r.pos -= 4
|
||||
r.errSyntax()
|
||||
}
|
||||
}
|
||||
|
||||
// fetchTrue fetches and checks remaining bytes of true keyword.
|
||||
func (r *Lexer) fetchTrue() {
|
||||
r.pos += 4
|
||||
if r.pos > len(r.Data) ||
|
||||
r.Data[r.pos-3] != 'r' ||
|
||||
r.Data[r.pos-2] != 'u' ||
|
||||
r.Data[r.pos-1] != 'e' ||
|
||||
(r.pos != len(r.Data) && !isTokenEnd(r.Data[r.pos])) {
|
||||
|
||||
r.pos -= 4
|
||||
r.errSyntax()
|
||||
}
|
||||
}
|
||||
|
||||
// fetchFalse fetches and checks remaining bytes of false keyword.
|
||||
func (r *Lexer) fetchFalse() {
|
||||
r.pos += 5
|
||||
if r.pos > len(r.Data) ||
|
||||
r.Data[r.pos-4] != 'a' ||
|
||||
r.Data[r.pos-3] != 'l' ||
|
||||
r.Data[r.pos-2] != 's' ||
|
||||
r.Data[r.pos-1] != 'e' ||
|
||||
(r.pos != len(r.Data) && !isTokenEnd(r.Data[r.pos])) {
|
||||
|
||||
r.pos -= 5
|
||||
r.errSyntax()
|
||||
}
|
||||
}
|
||||
|
||||
// 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{h.Data, h.Len}
|
||||
return *(*string)(unsafe.Pointer(&shdr))
|
||||
}
|
||||
|
||||
// fetchNumber scans a number literal token.
|
||||
func (r *Lexer) fetchNumber() {
|
||||
hasE := false
|
||||
afterE := false
|
||||
hasDot := false
|
||||
|
||||
r.pos++
|
||||
for i, c := range r.Data[r.pos:] {
|
||||
switch {
|
||||
case c >= '0' && c <= '9':
|
||||
afterE = false
|
||||
case c == '.' && !hasDot:
|
||||
hasDot = true
|
||||
case (c == 'e' || c == 'E') && !hasE:
|
||||
hasE = true
|
||||
hasDot = true
|
||||
afterE = true
|
||||
case (c == '+' || c == '-') && afterE:
|
||||
afterE = false
|
||||
default:
|
||||
r.pos += i
|
||||
if !isTokenEnd(c) {
|
||||
r.errSyntax()
|
||||
} else {
|
||||
r.token.byteValue = r.Data[r.start:r.pos]
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
r.pos = len(r.Data)
|
||||
r.token.byteValue = r.Data[r.start:]
|
||||
}
|
||||
|
||||
// findStringLen tries to scan into the string literal for ending quote char to determine required size.
|
||||
// The size will be exact if no escapes are present and may be inexact if there are escaped chars.
|
||||
func findStringLen(data []byte) (hasEscapes bool, length int) {
|
||||
delta := 0
|
||||
|
||||
for i := 0; i < len(data); i++ {
|
||||
switch data[i] {
|
||||
case '\\':
|
||||
i++
|
||||
delta++
|
||||
if i < len(data) && data[i] == 'u' {
|
||||
delta++
|
||||
}
|
||||
case '"':
|
||||
return (delta > 0), (i - delta)
|
||||
}
|
||||
}
|
||||
|
||||
return false, len(data)
|
||||
}
|
||||
|
||||
// processEscape processes a single escape sequence and returns number of bytes processed.
|
||||
func (r *Lexer) processEscape(data []byte) (int, error) {
|
||||
if len(data) < 2 {
|
||||
return 0, fmt.Errorf("syntax error at %v", string(data))
|
||||
}
|
||||
|
||||
c := data[1]
|
||||
switch c {
|
||||
case '"', '/', '\\':
|
||||
r.token.byteValue = append(r.token.byteValue, c)
|
||||
return 2, nil
|
||||
case 'b':
|
||||
r.token.byteValue = append(r.token.byteValue, '\b')
|
||||
return 2, nil
|
||||
case 'f':
|
||||
r.token.byteValue = append(r.token.byteValue, '\f')
|
||||
return 2, nil
|
||||
case 'n':
|
||||
r.token.byteValue = append(r.token.byteValue, '\n')
|
||||
return 2, nil
|
||||
case 'r':
|
||||
r.token.byteValue = append(r.token.byteValue, '\r')
|
||||
return 2, nil
|
||||
case 't':
|
||||
r.token.byteValue = append(r.token.byteValue, '\t')
|
||||
return 2, nil
|
||||
case 'u':
|
||||
default:
|
||||
return 0, fmt.Errorf("syntax error")
|
||||
}
|
||||
|
||||
var val rune
|
||||
|
||||
for i := 2; i < len(data) && i < 6; i++ {
|
||||
var v byte
|
||||
c = data[i]
|
||||
switch c {
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
v = c - '0'
|
||||
case 'a', 'b', 'c', 'd', 'e', 'f':
|
||||
v = c - 'a' + 10
|
||||
case 'A', 'B', 'C', 'D', 'E', 'F':
|
||||
v = c - 'A' + 10
|
||||
default:
|
||||
return 0, fmt.Errorf("syntax error")
|
||||
}
|
||||
|
||||
val <<= 4
|
||||
val |= rune(v)
|
||||
}
|
||||
|
||||
l := utf8.RuneLen(val)
|
||||
if l == -1 {
|
||||
return 0, fmt.Errorf("invalid unicode escape")
|
||||
}
|
||||
|
||||
var d [4]byte
|
||||
utf8.EncodeRune(d[:], val)
|
||||
r.token.byteValue = append(r.token.byteValue, d[:l]...)
|
||||
return 6, nil
|
||||
}
|
||||
|
||||
// fetchString scans a string literal token.
|
||||
func (r *Lexer) fetchString() {
|
||||
r.pos++
|
||||
data := r.Data[r.pos:]
|
||||
|
||||
hasEscapes, length := findStringLen(data)
|
||||
if !hasEscapes {
|
||||
r.token.byteValue = data[:length]
|
||||
r.pos += length + 1
|
||||
return
|
||||
}
|
||||
|
||||
r.token.byteValue = make([]byte, 0, length)
|
||||
p := 0
|
||||
for i := 0; i < len(data); {
|
||||
switch data[i] {
|
||||
case '"':
|
||||
r.pos += i + 1
|
||||
r.token.byteValue = append(r.token.byteValue, data[p:i]...)
|
||||
i++
|
||||
return
|
||||
|
||||
case '\\':
|
||||
r.token.byteValue = append(r.token.byteValue, data[p:i]...)
|
||||
off, err := r.processEscape(data[i:])
|
||||
if err != nil {
|
||||
r.errParse(err.Error())
|
||||
return
|
||||
}
|
||||
i += off
|
||||
p = i
|
||||
|
||||
default:
|
||||
i++
|
||||
}
|
||||
}
|
||||
r.errParse("unterminated string literal")
|
||||
}
|
||||
|
||||
// scanToken scans the next token if no token is currently available in the lexer.
|
||||
func (r *Lexer) scanToken() {
|
||||
if r.token.kind != tokenUndef || r.err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
r.fetchToken()
|
||||
}
|
||||
|
||||
// consume resets the current token to allow scanning the next one.
|
||||
func (r *Lexer) consume() {
|
||||
r.token.kind = tokenUndef
|
||||
r.token.delimValue = 0
|
||||
}
|
||||
|
||||
// Ok returns true if no error (including io.EOF) was encountered during scanning.
|
||||
func (r *Lexer) Ok() bool {
|
||||
return r.err == nil
|
||||
}
|
||||
|
||||
const maxErrorContextLen = 13
|
||||
|
||||
func (r *Lexer) errParse(what string) {
|
||||
if r.err == nil {
|
||||
var str string
|
||||
if len(r.Data)-r.pos <= maxErrorContextLen {
|
||||
str = string(r.Data)
|
||||
} else {
|
||||
str = string(r.Data[r.pos:r.pos+maxErrorContextLen-3]) + "..."
|
||||
}
|
||||
r.err = &LexerError{
|
||||
Reason: what,
|
||||
Offset: r.pos,
|
||||
Data: str,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Lexer) errSyntax() {
|
||||
r.errParse("syntax error")
|
||||
}
|
||||
|
||||
func (r *Lexer) errInvalidToken(expected string) {
|
||||
if r.err == nil {
|
||||
var str string
|
||||
if len(r.token.byteValue) <= maxErrorContextLen {
|
||||
str = string(r.token.byteValue)
|
||||
} else {
|
||||
str = string(r.token.byteValue[:maxErrorContextLen-3]) + "..."
|
||||
}
|
||||
r.err = &LexerError{
|
||||
Reason: fmt.Sprintf("expected %s", expected),
|
||||
Offset: r.pos,
|
||||
Data: str,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delim consumes a token and verifies that it is the given delimiter.
|
||||
func (r *Lexer) Delim(c byte) {
|
||||
if r.token.kind == tokenUndef && r.Ok() {
|
||||
r.fetchToken()
|
||||
}
|
||||
if !r.Ok() || r.token.delimValue != c {
|
||||
r.errInvalidToken(string([]byte{c}))
|
||||
}
|
||||
r.consume()
|
||||
}
|
||||
|
||||
// IsDelim returns true if there was no scanning error and next token is the given delimiter.
|
||||
func (r *Lexer) IsDelim(c byte) bool {
|
||||
if r.token.kind == tokenUndef && r.Ok() {
|
||||
r.fetchToken()
|
||||
}
|
||||
return !r.Ok() || r.token.delimValue == c
|
||||
}
|
||||
|
||||
// Null verifies that the next token is null and consumes it.
|
||||
func (r *Lexer) Null() {
|
||||
if r.token.kind == tokenUndef && r.Ok() {
|
||||
r.fetchToken()
|
||||
}
|
||||
if !r.Ok() || r.token.kind != tokenNull {
|
||||
r.errInvalidToken("null")
|
||||
}
|
||||
r.consume()
|
||||
}
|
||||
|
||||
// IsNull returns true if the next token is a null keyword.
|
||||
func (r *Lexer) IsNull() bool {
|
||||
if r.token.kind == tokenUndef && r.Ok() {
|
||||
r.fetchToken()
|
||||
}
|
||||
return r.Ok() && r.token.kind == tokenNull
|
||||
}
|
||||
|
||||
// Skip skips a single token.
|
||||
func (r *Lexer) Skip() {
|
||||
if r.token.kind == tokenUndef && r.Ok() {
|
||||
r.fetchToken()
|
||||
}
|
||||
r.consume()
|
||||
}
|
||||
|
||||
// SkipRecursive skips next array or object completely, or just skips a single token if not
|
||||
// an array/object.
|
||||
//
|
||||
// Note: no syntax validation is performed on the skipped data.
|
||||
func (r *Lexer) SkipRecursive() {
|
||||
r.scanToken()
|
||||
|
||||
var start, end byte
|
||||
|
||||
if r.token.delimValue == '{' {
|
||||
start, end = '{', '}'
|
||||
} else if r.token.delimValue == '[' {
|
||||
start, end = '[', ']'
|
||||
} else {
|
||||
r.consume()
|
||||
return
|
||||
}
|
||||
|
||||
r.consume()
|
||||
|
||||
level := 1
|
||||
inQuotes := false
|
||||
wasEscape := false
|
||||
|
||||
for i, c := range r.Data[r.pos:] {
|
||||
switch {
|
||||
case c == start && !inQuotes:
|
||||
level++
|
||||
case c == end && !inQuotes:
|
||||
level--
|
||||
if level == 0 {
|
||||
r.pos += i + 1
|
||||
return
|
||||
}
|
||||
case c == '\\' && inQuotes:
|
||||
wasEscape = true
|
||||
continue
|
||||
case c == '"' && inQuotes:
|
||||
inQuotes = wasEscape
|
||||
case c == '"':
|
||||
inQuotes = true
|
||||
}
|
||||
wasEscape = false
|
||||
}
|
||||
r.pos = len(r.Data)
|
||||
r.err = io.EOF
|
||||
}
|
||||
|
||||
// Raw fetches the next item recursively as a data slice
|
||||
func (r *Lexer) Raw() []byte {
|
||||
r.SkipRecursive()
|
||||
if !r.Ok() {
|
||||
return nil
|
||||
}
|
||||
return r.Data[r.start:r.pos]
|
||||
}
|
||||
|
||||
// UnsafeString returns the string value if the token is a string literal.
|
||||
//
|
||||
// Warning: returned string may point to the input buffer, so the string should not outlive
|
||||
// the input buffer. Intended pattern of usage is as an argument to a switch statement.
|
||||
func (r *Lexer) UnsafeString() string {
|
||||
if r.token.kind == tokenUndef && r.Ok() {
|
||||
r.fetchToken()
|
||||
}
|
||||
if !r.Ok() || r.token.kind != tokenString {
|
||||
r.errInvalidToken("string")
|
||||
return ""
|
||||
}
|
||||
|
||||
ret := bytesToStr(r.token.byteValue)
|
||||
r.consume()
|
||||
return ret
|
||||
}
|
||||
|
||||
// String reads a string literal.
|
||||
func (r *Lexer) String() string {
|
||||
if r.token.kind == tokenUndef && r.Ok() {
|
||||
r.fetchToken()
|
||||
}
|
||||
if !r.Ok() || r.token.kind != tokenString {
|
||||
r.errInvalidToken("string")
|
||||
return ""
|
||||
|
||||
}
|
||||
ret := string(r.token.byteValue)
|
||||
r.consume()
|
||||
return ret
|
||||
}
|
||||
|
||||
// Bool reads a true or false boolean keyword.
|
||||
func (r *Lexer) Bool() bool {
|
||||
if r.token.kind == tokenUndef && r.Ok() {
|
||||
r.fetchToken()
|
||||
}
|
||||
if !r.Ok() || r.token.kind != tokenBool {
|
||||
r.errInvalidToken("bool")
|
||||
return false
|
||||
|
||||
}
|
||||
ret := r.token.boolValue
|
||||
r.consume()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (r *Lexer) number() string {
|
||||
if r.token.kind == tokenUndef && r.Ok() {
|
||||
r.fetchToken()
|
||||
}
|
||||
if !r.Ok() || r.token.kind != tokenNumber {
|
||||
r.errInvalidToken("number")
|
||||
return ""
|
||||
|
||||
}
|
||||
ret := bytesToStr(r.token.byteValue)
|
||||
r.consume()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (r *Lexer) Uint8() uint8 {
|
||||
s := r.number()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseUint(s, 10, 8)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return uint8(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Uint16() uint16 {
|
||||
s := r.number()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseUint(s, 10, 16)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return uint16(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Uint32() uint32 {
|
||||
s := r.number()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseUint(s, 10, 32)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return uint32(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Uint64() uint64 {
|
||||
s := r.number()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (r *Lexer) Uint() uint {
|
||||
return uint(r.Uint64())
|
||||
}
|
||||
|
||||
func (r *Lexer) Int8() int8 {
|
||||
s := r.number()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseInt(s, 10, 8)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return int8(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Int16() int16 {
|
||||
s := r.number()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseInt(s, 10, 16)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return int16(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Int32() int32 {
|
||||
s := r.number()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseInt(s, 10, 32)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return int32(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Int64() int64 {
|
||||
s := r.number()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (r *Lexer) Int() int {
|
||||
return int(r.Int64())
|
||||
}
|
||||
|
||||
func (r *Lexer) Uint8Str() uint8 {
|
||||
s := r.UnsafeString()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseUint(s, 10, 8)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return uint8(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Uint16Str() uint16 {
|
||||
s := r.UnsafeString()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseUint(s, 10, 16)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return uint16(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Uint32Str() uint32 {
|
||||
s := r.UnsafeString()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseUint(s, 10, 32)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return uint32(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Uint64Str() uint64 {
|
||||
s := r.UnsafeString()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (r *Lexer) UintStr() uint {
|
||||
return uint(r.Uint64Str())
|
||||
}
|
||||
|
||||
func (r *Lexer) Int8Str() int8 {
|
||||
s := r.UnsafeString()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseInt(s, 10, 8)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return int8(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Int16Str() int16 {
|
||||
s := r.UnsafeString()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseInt(s, 10, 16)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return int16(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Int32Str() int32 {
|
||||
s := r.UnsafeString()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseInt(s, 10, 32)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return int32(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Int64Str() int64 {
|
||||
s := r.UnsafeString()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (r *Lexer) IntStr() int {
|
||||
return int(r.Int64Str())
|
||||
}
|
||||
|
||||
func (r *Lexer) Float32() float32 {
|
||||
s := r.number()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseFloat(s, 32)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return float32(n)
|
||||
}
|
||||
|
||||
func (r *Lexer) Float64() float64 {
|
||||
s := r.number()
|
||||
if !r.Ok() {
|
||||
return 0
|
||||
}
|
||||
|
||||
n, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
r.err = &LexerError{
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (r *Lexer) Error() error {
|
||||
return r.err
|
||||
}
|
||||
|
||||
func (r *Lexer) AddError(e error) {
|
||||
if r.err == nil {
|
||||
r.err = e
|
||||
}
|
||||
}
|
||||
|
||||
// Interface fetches an interface{} analogous to the 'encoding/json' package.
|
||||
func (r *Lexer) Interface() interface{} {
|
||||
if r.token.kind == tokenUndef && r.Ok() {
|
||||
r.fetchToken()
|
||||
}
|
||||
|
||||
if !r.Ok() {
|
||||
return nil
|
||||
}
|
||||
switch r.token.kind {
|
||||
case tokenString:
|
||||
return r.String()
|
||||
case tokenNumber:
|
||||
return r.Float64()
|
||||
case tokenBool:
|
||||
return r.Bool()
|
||||
case tokenNull:
|
||||
r.Null()
|
||||
return nil
|
||||
}
|
||||
|
||||
if r.token.delimValue == '{' {
|
||||
r.consume()
|
||||
|
||||
ret := map[string]interface{}{}
|
||||
for !r.IsDelim('}') {
|
||||
key := r.String()
|
||||
r.WantColon()
|
||||
ret[key] = r.Interface()
|
||||
r.WantComma()
|
||||
}
|
||||
r.Delim('}')
|
||||
|
||||
if r.Ok() {
|
||||
return ret
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
} else if r.token.delimValue == '[' {
|
||||
r.consume()
|
||||
|
||||
var ret []interface{}
|
||||
for !r.IsDelim(']') {
|
||||
ret = append(ret, r.Interface())
|
||||
r.WantComma()
|
||||
}
|
||||
r.Delim(']')
|
||||
|
||||
if r.Ok() {
|
||||
return ret
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
r.errSyntax()
|
||||
return nil
|
||||
}
|
||||
|
||||
// WantComma requires a comma to be present before fetching next token.
|
||||
func (r *Lexer) WantComma() {
|
||||
r.wantSep = ','
|
||||
r.firstElement = false
|
||||
}
|
||||
|
||||
// WantColon requires a colon to be present before fetching next token.
|
||||
func (r *Lexer) WantColon() {
|
||||
r.wantSep = ':'
|
||||
r.firstElement = false
|
||||
}
|
||||
192
vendor/github.com/mailru/easyjson/jlexer/lexer_test.go
generated
vendored
Normal file
192
vendor/github.com/mailru/easyjson/jlexer/lexer_test.go
generated
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
package jlexer
|
||||
|
||||
import (
|
||||
"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: `"test"junk`, want: "test"},
|
||||
|
||||
{toParse: `5`, wantError: true}, // not a string
|
||||
{toParse: `"\x"`, wantError: true}, // invalid escape
|
||||
{toParse: `"\ud800"`, wantError: true}, // invalid utf-8 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 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"},
|
||||
} {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
273
vendor/github.com/mailru/easyjson/jwriter/writer.go
generated
vendored
Normal file
273
vendor/github.com/mailru/easyjson/jwriter/writer.go
generated
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
// Package jwriter contains a JSON writer.
|
||||
package jwriter
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strconv"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/mailru/easyjson/buffer"
|
||||
)
|
||||
|
||||
// Writer is a JSON writer.
|
||||
type Writer struct {
|
||||
Error error
|
||||
Buffer buffer.Buffer
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (w *Writer) BuildBytes() ([]byte, error) {
|
||||
if w.Error != nil {
|
||||
return nil, w.Error
|
||||
}
|
||||
|
||||
return w.Buffer.BuildBytes(), 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)
|
||||
}
|
||||
|
||||
// RawByte 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")
|
||||
}
|
||||
}
|
||||
|
||||
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 (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); {
|
||||
// single-with character
|
||||
if c := s[i]; c < utf8.RuneSelf {
|
||||
var escape byte
|
||||
switch c {
|
||||
case '\t':
|
||||
escape = 't'
|
||||
case '\r':
|
||||
escape = 'r'
|
||||
case '\n':
|
||||
escape = 'n'
|
||||
case '\\':
|
||||
escape = '\\'
|
||||
case '"':
|
||||
escape = '"'
|
||||
case '<', '>':
|
||||
// do nothing
|
||||
default:
|
||||
if c >= 0x20 {
|
||||
// no escaping is required
|
||||
i++
|
||||
continue
|
||||
}
|
||||
}
|
||||
if escape != 0 {
|
||||
w.Buffer.AppendString(s[p:i])
|
||||
w.Buffer.AppendByte('\\')
|
||||
w.Buffer.AppendByte(escape)
|
||||
} else {
|
||||
w.Buffer.AppendString(s[p:i])
|
||||
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
|
||||
78
vendor/github.com/mailru/easyjson/parser/parser.go
generated
vendored
Normal file
78
vendor/github.com/mailru/easyjson/parser/parser.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
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.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) error {
|
||||
var err error
|
||||
if p.PkgPath, err = getPkgPath(fname); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, fname, nil, parser.ParseComments)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ast.Walk(&visitor{Parser: p}, f)
|
||||
return nil
|
||||
}
|
||||
29
vendor/github.com/mailru/easyjson/parser/parser_unix.go
generated
vendored
Normal file
29
vendor/github.com/mailru/easyjson/parser/parser_unix.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// +build !windows
|
||||
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func getPkgPath(fname string) (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 {
|
||||
return path.Dir(rel), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("file '%v' is not in GOPATH", fname)
|
||||
}
|
||||
33
vendor/github.com/mailru/easyjson/parser/parser_windows.go
generated
vendored
Normal file
33
vendor/github.com/mailru/easyjson/parser/parser_windows.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func normalizePath(path string) string {
|
||||
return strings.Replace(path, "\\", "/", -1)
|
||||
}
|
||||
|
||||
func getPkgPath(fname string) (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 {
|
||||
return path.Dir(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 marshalling.
|
||||
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
|
||||
}
|
||||
133
vendor/github.com/mailru/easyjson/tests/basic_test.go
generated
vendored
Normal file
133
vendor/github.com/mailru/easyjson/tests/basic_test.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
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},
|
||||
{&unexportedStructValue, unexportedStructString},
|
||||
{&excludedFieldValue, excludedFieldString},
|
||||
{&mapsValue, mapsString},
|
||||
{&deepNestValue, deepNestString},
|
||||
{&IntsValue, IntsString},
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
545
vendor/github.com/mailru/easyjson/tests/data.go
generated
vendored
Normal file
545
vendor/github.com/mailru/easyjson/tests/data.go
generated
vendored
Normal file
@@ -0,0 +1,545 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"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":[],` +
|
||||
|
||||
`"SubPtrSlice":[{"Value":"p1","Value2":""},{"Value":"p2","Value2":""}],` +
|
||||
`"SubPtrSliceNil":[],` +
|
||||
|
||||
`"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
|
||||
}
|
||||
|
||||
var stdMarshalerValue = StdMarshaler{T: time.Date(2016, 01, 02, 14, 15, 10, 0, time.UTC)}
|
||||
var stdMarshalerString = `{"T":"2016-01-02T14:15:10Z"}`
|
||||
|
||||
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 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
|
||||
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": nil,
|
||||
},
|
||||
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":[]` +
|
||||
`},` +
|
||||
`"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]`
|
||||
|
||||
type RequiredOptionalStruct struct {
|
||||
FirstName string `json:"first_name,required"`
|
||||
Lastname string `json:"last_name"`
|
||||
}
|
||||
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 (
|
||||
"testing"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
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. UnmarshallJSON didn`t expect error: %v", tc.json, err)
|
||||
}
|
||||
} else {
|
||||
if fmt.Sprintf("%v", err) != tc.errorMessage {
|
||||
t.Errorf("%s. UnmarshallJSON 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":""}`
|
||||
Reference in New Issue
Block a user