gojay

high performance JSON encoder/decoder with stream API for Golang
git clone git://git.lair.cx/gojay
Log | Files | Refs | README | LICENSE

commit 5c45cc8f3d0ad91d4278919db98b40a4d57d8c4b
parent 1398296d938f9fae26750ddc2fe356b6d897f799
Author: Yongbin Kim <iam@yongbin.kim>
Date:   Mon, 10 Oct 2022 18:55:26 +0900

Remove many uninterested files

I don't care about these benchmarks. Seriously, I don't think I should download all those JSON libraries...

Signed-off-by: Yongbin Kim <iam@yongbin.kim>

Diffstat:
M.gitignore | 1+
DGopkg.lock | 163-------------------------------------------------------------------------------
DGopkg.toml | 23-----------------------
MREADME.md | 4++--
Dbenchmarks/benchmarks_large.go | 177-------------------------------------------------------------------------------
Dbenchmarks/benchmarks_large_easyjson.go | 426-------------------------------------------------------------------------------
Dbenchmarks/benchmarks_medium.go | 316-------------------------------------------------------------------------------
Dbenchmarks/benchmarks_medium_easyjson.go | 560-------------------------------------------------------------------------------
Dbenchmarks/benchmarks_small.go | 76----------------------------------------------------------------------------
Dbenchmarks/benchmarks_small_easyjson.go | 186-------------------------------------------------------------------------------
Dbenchmarks/decoder/.gitignore | 2--
Dbenchmarks/decoder/Makefile | 36------------------------------------
Dbenchmarks/decoder/decoder.go | 1-
Dbenchmarks/decoder/decoder_bench_float_test.go | 28----------------------------
Dbenchmarks/decoder/decoder_bench_large_test.go | 59-----------------------------------------------------------
Dbenchmarks/decoder/decoder_bench_medium_test.go | 72------------------------------------------------------------------------
Dbenchmarks/decoder/decoder_bench_small_test.go | 69---------------------------------------------------------------------
Dbenchmarks/decoder/decoder_large_test.go | 23-----------------------
Dbenchmarks/decoder/decoder_medium_test.go | 18------------------
Dbenchmarks/decoder/decoder_small_test.go | 29-----------------------------
Dbenchmarks/encoder/.gitignore | 2--
Dbenchmarks/encoder/Makefile | 32--------------------------------
Dbenchmarks/encoder/encoder_bench_large_test.go | 56--------------------------------------------------------
Dbenchmarks/encoder/encoder_bench_medium_test.go | 57---------------------------------------------------------
Dbenchmarks/encoder/encoder_bench_small_test.go | 76----------------------------------------------------------------------------
Dbenchmarks/encoder/encoder_large_test.go | 1-
Dbenchmarks/encoder/encoder_medium_test.go | 1-
Dbenchmarks/encoder/encoder_small_test.go | 1-
Mdecode_example_test.go | 2+-
Mencode_example_test.go | 2+-
Dexamples/encode-decode-map/main.go | 100-------------------------------------------------------------------------------
Dexamples/fuzz/Makefile | 12------------
Dexamples/fuzz/main.go | 46----------------------------------------------
Dexamples/http-benchmarks/Makefile | 5-----
Dexamples/http-benchmarks/README.md | 53-----------------------------------------------------
Dexamples/http-benchmarks/gojay/main.go | 158-------------------------------------------------------------------------------
Dexamples/http-benchmarks/post.lua | 220-------------------------------------------------------------------------------
Dexamples/http-benchmarks/standard/main.go | 42------------------------------------------
Dexamples/http-json/main.go | 72------------------------------------------------------------------------
Dexamples/websocket/client/client.go | 27---------------------------
Dexamples/websocket/comm/comm.go | 107-------------------------------------------------------------------------------
Dexamples/websocket/main.go | 75---------------------------------------------------------------------------
Dexamples/websocket/server/server.go | 82-------------------------------------------------------------------------------
Mgo.mod | 27+++++++--------------------
Mgo.sum | 185++++---------------------------------------------------------------------------
Dgojay/README.md | 61-------------------------------------------------------------
Dgojay/codegen/field.go | 168-------------------------------------------------------------------------------
Dgojay/codegen/generator.go | 255-------------------------------------------------------------------------------
Dgojay/codegen/generator_test.go | 72------------------------------------------------------------------------
Dgojay/codegen/helper.go | 102-------------------------------------------------------------------------------
Dgojay/codegen/options.go | 55-------------------------------------------------------
Dgojay/codegen/struct.go | 345-------------------------------------------------------------------------------
Dgojay/codegen/template.go | 321-------------------------------------------------------------------------------
Dgojay/codegen/template_test.go | 19-------------------
Dgojay/codegen/test/annotated_struct/encoding.go | 289------------------------------------------------------------------------------
Dgojay/codegen/test/annotated_struct/encoding_test.go | 126-------------------------------------------------------------------------------
Dgojay/codegen/test/annotated_struct/message.go | 21---------------------
Dgojay/codegen/test/annotated_struct/sub_message.go | 10----------
Dgojay/codegen/test/basic_struct/encoding.go | 267-------------------------------------------------------------------------------
Dgojay/codegen/test/basic_struct/encoding_test.go | 118-------------------------------------------------------------------------------
Dgojay/codegen/test/basic_struct/message.go | 18------------------
Dgojay/codegen/test/basic_struct/sub_message.go | 10----------
Dgojay/codegen/test/embedded_struct/encoding.go | 309-------------------------------------------------------------------------------
Dgojay/codegen/test/embedded_struct/encoding_test.go | 106-------------------------------------------------------------------------------
Dgojay/codegen/test/embedded_struct/message.go | 20--------------------
Dgojay/codegen/test/embedded_struct/sub_message.go | 9---------
Dgojay/codegen/test/pooled_struct/encoding.go | 302------------------------------------------------------------------------------
Dgojay/codegen/test/pooled_struct/encoding_test.go | 123-------------------------------------------------------------------------------
Dgojay/codegen/test/pooled_struct/message.go | 15---------------
Dgojay/codegen/test/pooled_struct/sub_message.go | 10----------
Dgojay/gojay.go | 23-----------------------
Mgojay_example_test.go | 2+-
72 files changed, 22 insertions(+), 6864 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -3,3 +3,4 @@ vendor *.log *.test .vscode +.idea diff --git a/Gopkg.lock b/Gopkg.lock @@ -1,163 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - digest = "1:1a37f9f2ae10d161d9688fb6008ffa14e1631e5068cc3e9698008b9e8d40d575" - name = "cloud.google.com/go" - packages = ["compute/metadata"] - pruneopts = "" - revision = "457ea5c15ccf3b87db582c450e80101989da35f7" - version = "v0.40.0" - -[[projects]] - digest = "1:968d8903d598e3fae738325d3410f33f07ea6a2b9ee5591e9c262ee37df6845a" - name = "github.com/go-errors/errors" - packages = ["."] - pruneopts = "" - revision = "a6af135bd4e28680facf08a3d206b454abc877a4" - version = "v1.0.1" - -[[projects]] - digest = "1:529d738b7976c3848cae5cf3a8036440166835e389c1f617af701eeb12a0518d" - name = "github.com/golang/protobuf" - packages = ["proto"] - pruneopts = "" - revision = "b5d812f8a3706043e23a9cd5babf2e5423744d30" - version = "v1.3.1" - -[[projects]] - branch = "master" - digest = "1:cae59d7b8243c671c9f544965522ba35c0fec48ee80adb9f1400cd2f33abbbec" - name = "github.com/mailru/easyjson" - packages = [ - ".", - "buffer", - "jlexer", - "jwriter", - ] - pruneopts = "" - revision = "1ea4449da9834f4d333f1cc461c374aea217d249" - -[[projects]] - digest = "1:1d7e1867c49a6dd9856598ef7c3123604ea3daabf5b83f303ff457bcbc410b1d" - name = "github.com/pkg/errors" - packages = ["."] - pruneopts = "" - revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4" - version = "v0.8.1" - -[[projects]] - digest = "1:8d4bbd8ab012efc77ab6b97286f2aff262bcdeac9803bb57d75cf7d0a5e6a877" - name = "github.com/viant/assertly" - packages = ["."] - pruneopts = "" - revision = "04f45e0aeb6f3455884877b047a97bcc95dc9493" - version = "v0.4.8" - -[[projects]] - digest = "1:5913451bc2d274673c0716efe226a137625740cd9380641f4d8300ff4f2d82a0" - name = "github.com/viant/toolbox" - packages = [ - ".", - "cred", - "data", - "storage", - "url", - ] - pruneopts = "" - revision = "1be8e4d172138324f40d55ea61a2aeab0c5ce864" - version = "v0.24.0" - -[[projects]] - branch = "master" - digest = "1:9d150270ca2c3356f2224a0878daa1652e4d0b25b345f18b4f6e156cc4b8ec5e" - name = "golang.org/x/crypto" - packages = [ - "blowfish", - "curve25519", - "ed25519", - "ed25519/internal/edwards25519", - "internal/chacha20", - "internal/subtle", - "poly1305", - "ssh", - ] - pruneopts = "" - revision = "f99c8df09eb5bff426315721bfa5f16a99cad32c" - -[[projects]] - branch = "master" - digest = "1:5a56f211e7c12a65c5585c629457a2fb91d8719844ee8fab92727ea8adb5721c" - name = "golang.org/x/net" - packages = [ - "context", - "context/ctxhttp", - "websocket", - ] - pruneopts = "" - revision = "461777fb6f67e8cb9d70cda16573678d085a74cf" - -[[projects]] - branch = "master" - digest = "1:01bdbbc604dcd5afb6f66a717f69ad45e9643c72d5bc11678d44ffa5c50f9e42" - name = "golang.org/x/oauth2" - packages = [ - ".", - "google", - "internal", - "jws", - "jwt", - ] - pruneopts = "" - revision = "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33" - -[[projects]] - branch = "master" - digest = "1:8ddb956f67d4c176abbbc42b7514aaeaf9ea30daa24e27d2cf30ad82f9334a2c" - name = "golang.org/x/sys" - packages = ["cpu"] - pruneopts = "" - revision = "1e42afee0f762ed3d76e6dd942e4181855fd1849" - -[[projects]] - digest = "1:47f391ee443f578f01168347818cb234ed819521e49e4d2c8dd2fb80d48ee41a" - name = "google.golang.org/appengine" - packages = [ - ".", - "internal", - "internal/app_identity", - "internal/base", - "internal/datastore", - "internal/log", - "internal/modules", - "internal/remote_api", - "internal/urlfetch", - "urlfetch", - ] - pruneopts = "" - revision = "b2f4a3cf3c67576a2ee09e1fe62656a5086ce880" - version = "v1.6.1" - -[[projects]] - digest = "1:cedccf16b71e86db87a24f8d4c70b0a855872eb967cb906a66b95de56aefbd0d" - name = "gopkg.in/yaml.v2" - packages = ["."] - pruneopts = "" - revision = "51d6538a90f86fe93ac480b35f37b2be17fef232" - version = "v2.2.2" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - input-imports = [ - "github.com/go-errors/errors", - "github.com/mailru/easyjson", - "github.com/mailru/easyjson/jlexer", - "github.com/mailru/easyjson/jwriter", - "github.com/viant/assertly", - "github.com/viant/toolbox", - "github.com/viant/toolbox/url", - "golang.org/x/net/websocket", - ] - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml @@ -1,23 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" - - -ignored = ["github.com/francoispqt/benchmarks*","github.com/stretchr/testify*","github.com/stretchr/testify","github.com/json-iterator/go","github.com/buger/jsonparser"] diff --git a/README.md b/README.md @@ -47,7 +47,7 @@ Decoding is done through two different API similar to standard `encoding/json`: Example of basic stucture decoding with Unmarshal: ```go -import "github.com/francoispqt/gojay" +import "go.lair.cx/gojay" type user struct { id int @@ -379,7 +379,7 @@ Encoding is done through two different API similar to standard `encoding/json`: Example of basic structure encoding with Marshal: ```go -import "github.com/francoispqt/gojay" +import "go.lair.cx/gojay" type user struct { id int diff --git a/benchmarks/benchmarks_large.go b/benchmarks/benchmarks_large.go @@ -1,177 +0,0 @@ -package benchmarks - -import ( - "strconv" - - "github.com/francoispqt/gojay" -) - -type DSUser struct { - Username string -} - -func (m *DSUser) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "username": - return dec.AddString(&m.Username) - } - return nil -} -func (m *DSUser) NKeys() int { - return 1 -} -func (m *DSUser) IsNil() bool { - return m == nil -} -func (m *DSUser) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddStringKey("username", m.Username) -} - -type DSTopic struct { - Id int - Slug string -} - -func (m *DSTopic) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "id": - return dec.AddInt(&m.Id) - case "slug": - return dec.AddString(&m.Slug) - } - return nil -} -func (m *DSTopic) NKeys() int { - return 2 -} -func (m *DSTopic) IsNil() bool { - return m == nil -} -func (m *DSTopic) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddIntKey("id", m.Id) - enc.AddStringKey("slug", m.Slug) -} - -type DSTopics []*DSTopic - -func (t *DSTopics) UnmarshalJSONArray(dec *gojay.Decoder) error { - dsTopic := &DSTopic{} - *t = append(*t, dsTopic) - return dec.AddObject(dsTopic) -} - -func (m *DSTopics) MarshalJSONArray(enc *gojay.Encoder) { - for _, e := range *m { - enc.AddObject(e) - } -} -func (m *DSTopics) IsNil() bool { - return m == nil -} - -type DSTopicsList struct { - Topics DSTopics - MoreTopicsUrl string -} - -func (m *DSTopicsList) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "topics": - m.Topics = DSTopics{} - return dec.AddArray(&m.Topics) - case "more_topics_url": - return dec.AddString(&m.MoreTopicsUrl) - } - return nil -} -func (m *DSTopicsList) NKeys() int { - return 2 -} - -func (m *DSTopicsList) IsNil() bool { - return m == nil -} - -func (m *DSTopicsList) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddArrayKey("users", &m.Topics) - enc.AddStringKey("more_topics_url", m.MoreTopicsUrl) -} - -type DSUsers []*DSUser - -func (t *DSUsers) UnmarshalJSONArray(dec *gojay.Decoder) error { - dsUser := DSUser{} - *t = append(*t, &dsUser) - return dec.AddObject(&dsUser) -} - -func (m *DSUsers) MarshalJSONArray(enc *gojay.Encoder) { - for _, e := range *m { - enc.AddObject(e) - } -} -func (m *DSUsers) IsNil() bool { - return m == nil -} - -type LargePayload struct { - Users DSUsers - Topics *DSTopicsList -} - -func (m *LargePayload) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "users": - return dec.AddArray(&m.Users) - case "topics": - m.Topics = &DSTopicsList{} - return dec.AddObject(m.Topics) - } - return nil -} - -func (m *LargePayload) NKeys() int { - return 2 -} - -//easyjson:json -func (m *LargePayload) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddArrayKey("users", &m.Users) - enc.AddObjectKey("topics", m.Topics) -} - -func (m *LargePayload) IsNil() bool { - return m == nil -} - -var LargeFixture = []byte(` - {"users":[{"id":-1,"username":"system","avatar_template":"/user_avatar/discourse.metabase.com/system/{size}/6_1.png"},{"id":89,"username":"zergot","avatar_template":"https://avatars.discourse.org/v2/letter/z/0ea827/{size}.png"},{"id":1,"username":"sameer","avatar_template":"https://avatars.discourse.org/v2/letter/s/bbce88/{size}.png"},{"id":84,"username":"HenryMirror","avatar_template":"https://avatars.discourse.org/v2/letter/h/ecd19e/{size}.png"},{"id":73,"username":"fimp","avatar_template":"https://avatars.discourse.org/v2/letter/f/ee59a6/{size}.png"},{"id":14,"username":"agilliland","avatar_template":"/user_avatar/discourse.metabase.com/agilliland/{size}/26_1.png"},{"id":87,"username":"amir","avatar_template":"https://avatars.discourse.org/v2/letter/a/c37758/{size}.png"},{"id":82,"username":"waseem","avatar_template":"https://avatars.discourse.org/v2/letter/w/9dc877/{size}.png"},{"id":78,"username":"tovenaar","avatar_template":"https://avatars.discourse.org/v2/letter/t/9de0a6/{size}.png"},{"id":74,"username":"Ben","avatar_template":"https://avatars.discourse.org/v2/letter/b/df788c/{size}.png"},{"id":71,"username":"MarkLaFay","avatar_template":"https://avatars.discourse.org/v2/letter/m/3bc359/{size}.png"},{"id":72,"username":"camsaul","avatar_template":"/user_avatar/discourse.metabase.com/camsaul/{size}/70_1.png"},{"id":53,"username":"mhjb","avatar_template":"/user_avatar/discourse.metabase.com/mhjb/{size}/54_1.png"},{"id":58,"username":"jbwiv","avatar_template":"https://avatars.discourse.org/v2/letter/j/6bbea6/{size}.png"},{"id":70,"username":"Maggs","avatar_template":"https://avatars.discourse.org/v2/letter/m/bbce88/{size}.png"},{"id":69,"username":"andrefaria","avatar_template":"/user_avatar/discourse.metabase.com/andrefaria/{size}/65_1.png"},{"id":60,"username":"bencarter78","avatar_template":"/user_avatar/discourse.metabase.com/bencarter78/{size}/59_1.png"},{"id":55,"username":"vikram","avatar_template":"https://avatars.discourse.org/v2/letter/v/e47774/{size}.png"},{"id":68,"username":"edchan77","avatar_template":"/user_avatar/discourse.metabase.com/edchan77/{size}/66_1.png"},{"id":9,"username":"karthikd","avatar_template":"https://avatars.discourse.org/v2/letter/k/cab0a1/{size}.png"},{"id":23,"username":"arthurz","avatar_template":"/user_avatar/discourse.metabase.com/arthurz/{size}/32_1.png"},{"id":3,"username":"tom","avatar_template":"/user_avatar/discourse.metabase.com/tom/{size}/21_1.png"},{"id":50,"username":"LeoNogueira","avatar_template":"/user_avatar/discourse.metabase.com/leonogueira/{size}/52_1.png"},{"id":66,"username":"ss06vi","avatar_template":"https://avatars.discourse.org/v2/letter/s/3ab097/{size}.png"},{"id":34,"username":"mattcollins","avatar_template":"/user_avatar/discourse.metabase.com/mattcollins/{size}/41_1.png"},{"id":51,"username":"krmmalik","avatar_template":"/user_avatar/discourse.metabase.com/krmmalik/{size}/53_1.png"},{"id":46,"username":"odysseas","avatar_template":"https://avatars.discourse.org/v2/letter/o/5f8ce5/{size}.png"},{"id":5,"username":"jonthewayne","avatar_template":"/user_avatar/discourse.metabase.com/jonthewayne/{size}/18_1.png"},{"id":11,"username":"anandiyer","avatar_template":"/user_avatar/discourse.metabase.com/anandiyer/{size}/23_1.png"},{"id":25,"username":"alnorth","avatar_template":"/user_avatar/discourse.metabase.com/alnorth/{size}/34_1.png"},{"id":52,"username":"j_at_svg","avatar_template":"https://avatars.discourse.org/v2/letter/j/96bed5/{size}.png"},{"id":42,"username":"styts","avatar_template":"/user_avatar/discourse.metabase.com/styts/{size}/47_1.png"}],"topics":{"can_create_topic":false,"more_topics_url":"/c/uncategorized/l/latest?page=1","draft":null,"draft_key":"new_topic","draft_sequence":null,"per_page":30,"topics":[{"id":8,"title":"Welcome to Metabase's Discussion Forum","fancy_title":"Welcome to Metabase&rsquo;s Discussion Forum","slug":"welcome-to-metabases-discussion-forum","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"/images/welcome/discourse-edit-post-animated.gif","created_at":"2015-10-17T00:14:49.526Z","last_posted_at":"2015-10-17T00:14:49.557Z","bumped":true,"bumped_at":"2015-10-21T02:32:22.486Z","unseen":false,"pinned":true,"unpinned":null,"excerpt":"Welcome to Metabase&#39;s discussion forum. This is a place to get help on installation, setting up as well as sharing tips and tricks.","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":197,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"system","category_id":1,"pinned_globally":true,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":-1}]},{"id":169,"title":"Formatting Dates","fancy_title":"Formatting Dates","slug":"formatting-dates","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2016-01-14T06:30:45.311Z","last_posted_at":"2016-01-14T06:30:45.397Z","bumped":true,"bumped_at":"2016-01-14T06:30:45.397Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":11,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"zergot","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":89}]},{"id":168,"title":"Setting for google api key","fancy_title":"Setting for google api key","slug":"setting-for-google-api-key","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2016-01-13T17:14:31.799Z","last_posted_at":"2016-01-14T06:24:03.421Z","bumped":true,"bumped_at":"2016-01-14T06:24:03.421Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":16,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"zergot","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":89}]},{"id":167,"title":"Cannot see non-US timezones on the admin","fancy_title":"Cannot see non-US timezones on the admin","slug":"cannot-see-non-us-timezones-on-the-admin","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2016-01-13T17:07:36.764Z","last_posted_at":"2016-01-13T17:07:36.831Z","bumped":true,"bumped_at":"2016-01-13T17:07:36.831Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":11,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"zergot","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":89}]},{"id":164,"title":"External (Metabase level) linkages in data schema","fancy_title":"External (Metabase level) linkages in data schema","slug":"external-metabase-level-linkages-in-data-schema","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2016-01-11T13:51:02.286Z","last_posted_at":"2016-01-12T11:06:37.259Z","bumped":true,"bumped_at":"2016-01-12T11:06:37.259Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":32,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"zergot","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":89},{"extras":null,"description":"Frequent Poster","user_id":1}]},{"id":155,"title":"Query working on \"Questions\" but not in \"Pulses\"","fancy_title":"Query working on &ldquo;Questions&rdquo; but not in &ldquo;Pulses&rdquo;","slug":"query-working-on-questions-but-not-in-pulses","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2016-01-01T14:06:10.083Z","last_posted_at":"2016-01-08T22:37:51.772Z","bumped":true,"bumped_at":"2016-01-08T22:37:51.772Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":72,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"agilliland","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":84},{"extras":null,"description":"Frequent Poster","user_id":73},{"extras":"latest","description":"Most Recent Poster","user_id":14}]},{"id":161,"title":"Pulses posted to Slack don't show question output","fancy_title":"Pulses posted to Slack don&rsquo;t show question output","slug":"pulses-posted-to-slack-dont-show-question-output","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":"/uploads/default/original/1X/9d2806517bf3598b10be135b2c58923b47ba23e7.png","created_at":"2016-01-08T22:09:58.205Z","last_posted_at":"2016-01-08T22:28:44.685Z","bumped":true,"bumped_at":"2016-01-08T22:28:44.685Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":34,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":87},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":152,"title":"Should we build Kafka connecter or Kafka plugin","fancy_title":"Should we build Kafka connecter or Kafka plugin","slug":"should-we-build-kafka-connecter-or-kafka-plugin","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2015-12-28T20:37:23.501Z","last_posted_at":"2015-12-31T18:16:45.477Z","bumped":true,"bumped_at":"2015-12-31T18:16:45.477Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":84,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":82},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1}]},{"id":147,"title":"Change X and Y on graph","fancy_title":"Change X and Y on graph","slug":"change-x-and-y-on-graph","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2015-12-21T17:52:46.581Z","last_posted_at":"2015-12-21T17:52:46.684Z","bumped":true,"bumped_at":"2015-12-21T18:19:13.003Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":68,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"tovenaar","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":78}]},{"id":142,"title":"Issues sending mail via office365 relay","fancy_title":"Issues sending mail via office365 relay","slug":"issues-sending-mail-via-office365-relay","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2015-12-16T10:38:47.315Z","last_posted_at":"2015-12-21T09:26:27.167Z","bumped":true,"bumped_at":"2015-12-21T09:26:27.167Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":122,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"Ben","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":74},{"extras":null,"description":"Frequent Poster","user_id":1}]},{"id":137,"title":"I see triplicates of my mongoDB collections","fancy_title":"I see triplicates of my mongoDB collections","slug":"i-see-triplicates-of-my-mongodb-collections","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2015-12-14T13:33:03.426Z","last_posted_at":"2015-12-17T18:40:05.487Z","bumped":true,"bumped_at":"2015-12-17T18:40:05.487Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":97,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"MarkLaFay","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":71},{"extras":null,"description":"Frequent Poster","user_id":14}]},{"id":140,"title":"Google Analytics plugin","fancy_title":"Google Analytics plugin","slug":"google-analytics-plugin","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2015-12-15T13:00:55.644Z","last_posted_at":"2015-12-15T13:00:55.705Z","bumped":true,"bumped_at":"2015-12-15T13:00:55.705Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":105,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"fimp","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":73}]},{"id":138,"title":"With-mongo-connection failed: bad connection details:","fancy_title":"With-mongo-connection failed: bad connection details:","slug":"with-mongo-connection-failed-bad-connection-details","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2015-12-14T17:28:11.041Z","last_posted_at":"2015-12-14T17:28:11.111Z","bumped":true,"bumped_at":"2015-12-14T17:28:11.111Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":56,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"MarkLaFay","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":71}]},{"id":133,"title":"\"We couldn't understand your question.\" when I query mongoDB","fancy_title":"&ldquo;We couldn&rsquo;t understand your question.&rdquo; when I query mongoDB","slug":"we-couldnt-understand-your-question-when-i-query-mongodb","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2015-12-11T17:38:30.576Z","last_posted_at":"2015-12-14T13:31:26.395Z","bumped":true,"bumped_at":"2015-12-14T13:31:26.395Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":107,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"MarkLaFay","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":71},{"extras":null,"description":"Frequent Poster","user_id":72}]},{"id":129,"title":"My bar charts are all thin","fancy_title":"My bar charts are all thin","slug":"my-bar-charts-are-all-thin","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":"/uploads/default/original/1X/41bcf3b2a00dc7cfaff01cb3165d35d32a85bf1d.png","created_at":"2015-12-09T22:09:56.394Z","last_posted_at":"2015-12-11T19:00:45.289Z","bumped":true,"bumped_at":"2015-12-11T19:00:45.289Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":116,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"mhjb","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":53},{"extras":null,"description":"Frequent Poster","user_id":1}]},{"id":106,"title":"What is the expected return order of columns for graphing results when using raw SQL?","fancy_title":"What is the expected return order of columns for graphing results when using raw SQL?","slug":"what-is-the-expected-return-order-of-columns-for-graphing-results-when-using-raw-sql","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2015-11-24T19:07:14.561Z","last_posted_at":"2015-12-11T17:04:14.149Z","bumped":true,"bumped_at":"2015-12-11T17:04:14.149Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":153,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"jbwiv","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":58},{"extras":null,"description":"Frequent Poster","user_id":14}]},{"id":131,"title":"Set site url from admin panel","fancy_title":"Set site url from admin panel","slug":"set-site-url-from-admin-panel","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2015-12-10T06:22:46.042Z","last_posted_at":"2015-12-10T19:12:57.449Z","bumped":true,"bumped_at":"2015-12-10T19:12:57.449Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":77,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":70},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":127,"title":"Internationalization (i18n)","fancy_title":"Internationalization (i18n)","slug":"internationalization-i18n","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2015-12-08T16:55:37.397Z","last_posted_at":"2015-12-09T16:49:55.816Z","bumped":true,"bumped_at":"2015-12-09T16:49:55.816Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":85,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"agilliland","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":69},{"extras":"latest","description":"Most Recent Poster","user_id":14}]},{"id":109,"title":"Returning raw data with no filters always returns We couldn't understand your question","fancy_title":"Returning raw data with no filters always returns We couldn&rsquo;t understand your question","slug":"returning-raw-data-with-no-filters-always-returns-we-couldnt-understand-your-question","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2015-11-25T21:35:01.315Z","last_posted_at":"2015-12-09T10:26:12.255Z","bumped":true,"bumped_at":"2015-12-09T10:26:12.255Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":133,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"bencarter78","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":60},{"extras":null,"description":"Frequent Poster","user_id":14}]},{"id":103,"title":"Support for Cassandra?","fancy_title":"Support for Cassandra?","slug":"support-for-cassandra","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2015-11-20T06:45:31.741Z","last_posted_at":"2015-12-09T03:18:51.274Z","bumped":true,"bumped_at":"2015-12-09T03:18:51.274Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":169,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"vikram","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":55},{"extras":null,"description":"Frequent Poster","user_id":1}]},{"id":128,"title":"Mongo query with Date breaks [solved: Mongo 3.0 required]","fancy_title":"Mongo query with Date breaks [solved: Mongo 3.0 required]","slug":"mongo-query-with-date-breaks-solved-mongo-3-0-required","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":null,"created_at":"2015-12-08T18:30:56.562Z","last_posted_at":"2015-12-08T21:03:02.421Z","bumped":true,"bumped_at":"2015-12-08T21:03:02.421Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":102,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"edchan77","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":68},{"extras":null,"description":"Frequent Poster","user_id":1}]},{"id":23,"title":"Can this connect to MS SQL Server?","fancy_title":"Can this connect to MS SQL Server?","slug":"can-this-connect-to-ms-sql-server","posts_count":7,"reply_count":1,"highest_post_number":7,"image_url":null,"created_at":"2015-10-21T18:52:37.987Z","last_posted_at":"2015-12-07T17:41:51.609Z","bumped":true,"bumped_at":"2015-12-07T17:41:51.609Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":367,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":9},{"extras":null,"description":"Frequent Poster","user_id":23},{"extras":null,"description":"Frequent Poster","user_id":3},{"extras":null,"description":"Frequent Poster","user_id":50},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":121,"title":"Cannot restart metabase in docker","fancy_title":"Cannot restart metabase in docker","slug":"cannot-restart-metabase-in-docker","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2015-12-04T21:28:58.137Z","last_posted_at":"2015-12-04T23:02:00.488Z","bumped":true,"bumped_at":"2015-12-04T23:02:00.488Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":96,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":66},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1}]},{"id":85,"title":"Edit Max Rows Count","fancy_title":"Edit Max Rows Count","slug":"edit-max-rows-count","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2015-11-11T23:46:52.917Z","last_posted_at":"2015-11-24T01:01:14.569Z","bumped":true,"bumped_at":"2015-11-24T01:01:14.569Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":169,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":34},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1}]},{"id":96,"title":"Creating charts by querying more than one table at a time","fancy_title":"Creating charts by querying more than one table at a time","slug":"creating-charts-by-querying-more-than-one-table-at-a-time","posts_count":6,"reply_count":4,"highest_post_number":6,"image_url":null,"created_at":"2015-11-17T11:20:18.442Z","last_posted_at":"2015-11-21T02:12:25.995Z","bumped":true,"bumped_at":"2015-11-21T02:12:25.995Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":217,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":51},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1}]},{"id":90,"title":"Trying to add RDS postgresql as the database fails silently","fancy_title":"Trying to add RDS postgresql as the database fails silently","slug":"trying-to-add-rds-postgresql-as-the-database-fails-silently","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2015-11-14T23:45:02.967Z","last_posted_at":"2015-11-21T01:08:45.915Z","bumped":true,"bumped_at":"2015-11-21T01:08:45.915Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":162,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":46},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1}]},{"id":17,"title":"Deploy to Heroku isn't working","fancy_title":"Deploy to Heroku isn&rsquo;t working","slug":"deploy-to-heroku-isnt-working","posts_count":9,"reply_count":3,"highest_post_number":9,"image_url":null,"created_at":"2015-10-21T16:42:03.096Z","last_posted_at":"2015-11-20T18:34:14.044Z","bumped":true,"bumped_at":"2015-11-20T18:34:14.044Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":332,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"agilliland","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":5},{"extras":null,"description":"Frequent Poster","user_id":3},{"extras":null,"description":"Frequent Poster","user_id":11},{"extras":null,"description":"Frequent Poster","user_id":25},{"extras":"latest","description":"Most Recent Poster","user_id":14}]},{"id":100,"title":"Can I use DATEPART() in SQL queries?","fancy_title":"Can I use DATEPART() in SQL queries?","slug":"can-i-use-datepart-in-sql-queries","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2015-11-17T23:15:58.033Z","last_posted_at":"2015-11-18T00:19:48.763Z","bumped":true,"bumped_at":"2015-11-18T00:19:48.763Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":112,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":53},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":98,"title":"Feature Request: LDAP Authentication","fancy_title":"Feature Request: LDAP Authentication","slug":"feature-request-ldap-authentication","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2015-11-17T17:22:44.484Z","last_posted_at":"2015-11-17T17:22:44.577Z","bumped":true,"bumped_at":"2015-11-17T17:22:44.577Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":97,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"j_at_svg","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":52}]},{"id":87,"title":"Migrating from internal H2 to Postgres","fancy_title":"Migrating from internal H2 to Postgres","slug":"migrating-from-internal-h2-to-postgres","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2015-11-12T14:36:06.745Z","last_posted_at":"2015-11-12T18:05:10.796Z","bumped":true,"bumped_at":"2015-11-12T18:05:10.796Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":111,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":42},{"extras":"latest","description":"Most Recent Poster","user_id":1}]}]}} -`) - -func NewLargePayload() *LargePayload { - dsUsers := DSUsers{} - dsTopics := DSTopics{} - for i := 0; i < 100; i++ { - str := "test" + strconv.Itoa(i) - dsUsers = append( - dsUsers, - &DSUser{ - Username: str, - }, - ) - dsTopics = append( - dsTopics, - &DSTopic{ - Id: i, - Slug: str, - }, - ) - } - return &LargePayload{ - Users: dsUsers, - Topics: &DSTopicsList{ - Topics: dsTopics, - MoreTopicsUrl: "http://test.com", - }, - } -} diff --git a/benchmarks/benchmarks_large_easyjson.go b/benchmarks/benchmarks_large_easyjson.go @@ -1,426 +0,0 @@ -// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. - -package benchmarks - -import ( - json "encoding/json" - - easyjson "github.com/mailru/easyjson" - jlexer "github.com/mailru/easyjson/jlexer" - jwriter "github.com/mailru/easyjson/jwriter" -) - -// suppress unused package warning -var ( - _ *json.RawMessage - _ *jlexer.Lexer - _ *jwriter.Writer - _ easyjson.Marshaler -) - -func easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks(in *jlexer.Lexer, out *LargePayload) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeString() - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "Users": - if in.IsNull() { - in.Skip() - out.Users = nil - } else { - in.Delim('[') - if out.Users == nil { - if !in.IsDelim(']') { - out.Users = make(DSUsers, 0, 8) - } else { - out.Users = DSUsers{} - } - } else { - out.Users = (out.Users)[:0] - } - for !in.IsDelim(']') { - var v1 *DSUser - if in.IsNull() { - in.Skip() - v1 = nil - } else { - if v1 == nil { - v1 = new(DSUser) - } - (*v1).UnmarshalEasyJSON(in) - } - out.Users = append(out.Users, v1) - in.WantComma() - } - in.Delim(']') - } - case "Topics": - if in.IsNull() { - in.Skip() - out.Topics = nil - } else { - if out.Topics == nil { - out.Topics = new(DSTopicsList) - } - (*out.Topics).UnmarshalEasyJSON(in) - } - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks(out *jwriter.Writer, in LargePayload) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"Users\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - if in.Users == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { - out.RawString("null") - } else { - out.RawByte('[') - for v2, v3 := range in.Users { - if v2 > 0 { - out.RawByte(',') - } - if v3 == nil { - out.RawString("null") - } else { - (*v3).MarshalEasyJSON(out) - } - } - out.RawByte(']') - } - } - { - const prefix string = ",\"Topics\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - if in.Topics == nil { - out.RawString("null") - } else { - (*in.Topics).MarshalEasyJSON(out) - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v LargePayload) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v LargePayload) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *LargePayload) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *LargePayload) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks(l, v) -} -func easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks1(in *jlexer.Lexer, out *DSUser) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeString() - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "Username": - out.Username = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks1(out *jwriter.Writer, in DSUser) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"Username\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.Username)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v DSUser) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks1(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v DSUser) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks1(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *DSUser) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks1(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *DSUser) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks1(l, v) -} -func easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks2(in *jlexer.Lexer, out *DSTopicsList) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeString() - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "Topics": - if in.IsNull() { - in.Skip() - out.Topics = nil - } else { - in.Delim('[') - if out.Topics == nil { - if !in.IsDelim(']') { - out.Topics = make(DSTopics, 0, 8) - } else { - out.Topics = DSTopics{} - } - } else { - out.Topics = (out.Topics)[:0] - } - for !in.IsDelim(']') { - var v4 *DSTopic - if in.IsNull() { - in.Skip() - v4 = nil - } else { - if v4 == nil { - v4 = new(DSTopic) - } - (*v4).UnmarshalEasyJSON(in) - } - out.Topics = append(out.Topics, v4) - in.WantComma() - } - in.Delim(']') - } - case "MoreTopicsUrl": - out.MoreTopicsUrl = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks2(out *jwriter.Writer, in DSTopicsList) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"Topics\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - if in.Topics == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { - out.RawString("null") - } else { - out.RawByte('[') - for v5, v6 := range in.Topics { - if v5 > 0 { - out.RawByte(',') - } - if v6 == nil { - out.RawString("null") - } else { - (*v6).MarshalEasyJSON(out) - } - } - out.RawByte(']') - } - } - { - const prefix string = ",\"MoreTopicsUrl\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.MoreTopicsUrl)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v DSTopicsList) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks2(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v DSTopicsList) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks2(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *DSTopicsList) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks2(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *DSTopicsList) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks2(l, v) -} -func easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks3(in *jlexer.Lexer, out *DSTopic) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeString() - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "Id": - out.Id = int(in.Int()) - case "Slug": - out.Slug = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks3(out *jwriter.Writer, in DSTopic) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"Id\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.Int(int(in.Id)) - } - { - const prefix string = ",\"Slug\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.Slug)) - } - out.RawByte('}') -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v DSTopic) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks3(w, v) -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *DSTopic) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks3(l, v) -} diff --git a/benchmarks/benchmarks_medium.go b/benchmarks/benchmarks_medium.go @@ -1,316 +0,0 @@ -package benchmarks - -import "github.com/francoispqt/gojay" - -// Response from Clearbit API. Size: 2.4kb -var MediumFixture = []byte(`{ - "person": { - "id": "d50887ca-a6ce-4e59-b89f-14f0b5d03b03", - "name": { - "fullName": "Leonid Bugaev", - "givenName": "Leonid", - "familyName": "Bugaev" - }, - "email": "leonsbox@gmail.com", - "gender": "male", - "location": "Saint Petersburg, Saint Petersburg, RU", - "geo": { - "city": "Saint Petersburg", - "state": "Saint Petersburg", - "country": "Russia", - "lat": 59.9342802, - "lng": 30.3350986 - }, - "bio": "Senior engineer at Granify.com", - "site": "http://flickfaver.com", - "avatar": "https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/d50887ca-a6ce-4e59-b89f-14f0b5d03b03", - "employment": { - "name": "www.latera.ru", - "title": "Software Engineer", - "domain": "gmail.com" - }, - "facebook": { - "handle": "leonid.bugaev" - }, - "github": { - "handle": "buger", - "id": 14009, - "avatar": "https://avatars.githubusercontent.com/u/14009?v=3", - "company": "Granify", - "blog": "http://leonsbox.com", - "followers": 95, - "following": 10 - }, - "twitter": { - "handle": "flickfaver", - "id": 77004410, - "bio": null, - "followers": 2, - "following": 1, - "statuses": 5, - "favorites": 0, - "location": "", - "site": "http://flickfaver.com", - "avatar": null - }, - "linkedin": { - "handle": "in/leonidbugaev" - }, - "googleplus": { - "handle": null - }, - "angellist": { - "handle": "leonid-bugaev", - "id": 61541, - "bio": "Senior engineer at Granify.com", - "blog": "http://buger.github.com", - "site": "http://buger.github.com", - "followers": 41, - "avatar": "https://d1qb2nb5cznatu.cloudfront.net/users/61541-medium_jpg?1405474390" - }, - "klout": { - "handle": null, - "score": null - }, - "foursquare": { - "handle": null - }, - "aboutme": { - "handle": "leonid.bugaev", - "bio": null, - "avatar": null - }, - "gravatar": { - "handle": "buger", - "urls": [ - ], - "avatar": "http://1.gravatar.com/avatar/f7c8edd577d13b8930d5522f28123510", - "avatars": [ - { - "url": "http://1.gravatar.com/avatar/f7c8edd577d13b8930d5522f28123510", - "type": "thumbnail" - } - ] - }, - "fuzzy": false - }, - "company": null - }`) - -type CBAvatar struct { - Url string -} - -func (m *CBAvatar) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "avatars": - return dec.AddString(&m.Url) - } - return nil -} -func (m *CBAvatar) NKeys() int { - return 1 -} - -func (m *CBAvatar) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddStringKey("url", m.Url) -} - -func (m *CBAvatar) IsNil() bool { - return m == nil -} - -type Avatars []*CBAvatar - -func (t *Avatars) UnmarshalJSONArray(dec *gojay.Decoder) error { - avatar := CBAvatar{} - *t = append(*t, &avatar) - return dec.AddObject(&avatar) -} - -func (m *Avatars) MarshalJSONArray(enc *gojay.Encoder) { - for _, e := range *m { - enc.AddObject(e) - } -} -func (m *Avatars) IsNil() bool { - return m == nil -} - -type CBGravatar struct { - Avatars Avatars -} - -func (m *CBGravatar) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "avatars": - return dec.AddArray(&m.Avatars) - } - return nil -} -func (m *CBGravatar) NKeys() int { - return 1 -} - -func (m *CBGravatar) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddArrayKey("avatars", &m.Avatars) -} - -func (m *CBGravatar) IsNil() bool { - return m == nil -} - -type CBGithub struct { - Followers int -} - -func (m *CBGithub) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "followers": - return dec.AddInt(&m.Followers) - } - return nil -} - -func (m *CBGithub) NKeys() int { - return 1 -} - -func (m *CBGithub) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddIntKey("followers", m.Followers) -} - -func (m *CBGithub) IsNil() bool { - return m == nil -} - -type CBName struct { - FullName string `json:"fullName"` -} - -func (m *CBName) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "fullName": - return dec.AddString(&m.FullName) - } - return nil -} - -func (m *CBName) NKeys() int { - return 1 -} - -func (m *CBName) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddStringKey("fullName", m.FullName) -} - -func (m *CBName) IsNil() bool { - return m == nil -} - -type CBPerson struct { - Name *CBName `json:"name"` - Github *CBGithub `json:"github"` - Gravatar *CBGravatar -} - -func (m *CBPerson) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "name": - m.Name = &CBName{} - return dec.AddObject(m.Name) - case "github": - m.Github = &CBGithub{} - return dec.AddObject(m.Github) - case "gravatar": - m.Gravatar = &CBGravatar{} - return dec.AddObject(m.Gravatar) - } - return nil -} - -func (m *CBPerson) NKeys() int { - return 3 -} - -func (m *CBPerson) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddObjectKey("name", m.Name) - enc.AddObjectKey("github", m.Github) - enc.AddObjectKey("gravatar", m.Gravatar) -} - -func (m *CBPerson) IsNil() bool { - return m == nil -} - -//easyjson:json -type MediumPayload struct { - Person *CBPerson `json:"person"` - Company string `json:"company"` -} - -func (m *MediumPayload) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "person": - m.Person = &CBPerson{} - return dec.AddObject(m.Person) - case "company": - dec.AddString(&m.Company) - } - return nil -} - -func (m *MediumPayload) NKeys() int { - return 2 -} - -func (m *MediumPayload) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddObjectKey("person", m.Person) - // enc.AddStringKey("company", m.Company) -} - -func (m *MediumPayload) IsNil() bool { - return m == nil -} - -func NewMediumPayload() *MediumPayload { - return &MediumPayload{ - Company: "test", - Person: &CBPerson{ - Name: &CBName{ - FullName: "test", - }, - Github: &CBGithub{ - Followers: 100, - }, - Gravatar: &CBGravatar{ - Avatars: Avatars{ - &CBAvatar{ - Url: "http://test.com", - }, - &CBAvatar{ - Url: "http://test.com", - }, - &CBAvatar{ - Url: "http://test.com", - }, - &CBAvatar{ - Url: "http://test.com", - }, - &CBAvatar{ - Url: "http://test.com", - }, - &CBAvatar{ - Url: "http://test.com", - }, - &CBAvatar{ - Url: "http://test.com", - }, - &CBAvatar{ - Url: "http://test.com", - }, - }, - }, - }, - } -} diff --git a/benchmarks/benchmarks_medium_easyjson.go b/benchmarks/benchmarks_medium_easyjson.go @@ -1,560 +0,0 @@ -// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. - -package benchmarks - -import ( - json "encoding/json" - - easyjson "github.com/mailru/easyjson" - jlexer "github.com/mailru/easyjson/jlexer" - jwriter "github.com/mailru/easyjson/jwriter" -) - -// suppress unused package warning -var ( - _ *json.RawMessage - _ *jlexer.Lexer - _ *jwriter.Writer - _ easyjson.Marshaler -) - -func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks(in *jlexer.Lexer, out *MediumPayload) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeString() - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "person": - if in.IsNull() { - in.Skip() - out.Person = nil - } else { - if out.Person == nil { - out.Person = new(CBPerson) - } - (*out.Person).UnmarshalEasyJSON(in) - } - case "company": - out.Company = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks(out *jwriter.Writer, in MediumPayload) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"person\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - if in.Person == nil { - out.RawString("null") - } else { - (*in.Person).MarshalEasyJSON(out) - } - } - { - const prefix string = ",\"company\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.Company)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v MediumPayload) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v MediumPayload) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *MediumPayload) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *MediumPayload) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks(l, v) -} -func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks1(in *jlexer.Lexer, out *CBPerson) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeString() - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "name": - if in.IsNull() { - in.Skip() - out.Name = nil - } else { - if out.Name == nil { - out.Name = new(CBName) - } - (*out.Name).UnmarshalEasyJSON(in) - } - case "github": - if in.IsNull() { - in.Skip() - out.Github = nil - } else { - if out.Github == nil { - out.Github = new(CBGithub) - } - (*out.Github).UnmarshalEasyJSON(in) - } - case "Gravatar": - if in.IsNull() { - in.Skip() - out.Gravatar = nil - } else { - if out.Gravatar == nil { - out.Gravatar = new(CBGravatar) - } - (*out.Gravatar).UnmarshalEasyJSON(in) - } - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks1(out *jwriter.Writer, in CBPerson) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"name\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - if in.Name == nil { - out.RawString("null") - } else { - (*in.Name).MarshalEasyJSON(out) - } - } - { - const prefix string = ",\"github\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - if in.Github == nil { - out.RawString("null") - } else { - (*in.Github).MarshalEasyJSON(out) - } - } - { - const prefix string = ",\"Gravatar\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - if in.Gravatar == nil { - out.RawString("null") - } else { - (*in.Gravatar).MarshalEasyJSON(out) - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v CBPerson) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks1(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v CBPerson) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks1(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *CBPerson) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks1(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *CBPerson) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks1(l, v) -} -func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks2(in *jlexer.Lexer, out *CBName) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeString() - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "fullName": - out.FullName = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks2(out *jwriter.Writer, in CBName) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"fullName\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.FullName)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v CBName) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks2(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v CBName) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks2(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *CBName) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks2(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *CBName) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks2(l, v) -} -func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks3(in *jlexer.Lexer, out *CBGravatar) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeString() - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "Avatars": - if in.IsNull() { - in.Skip() - out.Avatars = nil - } else { - in.Delim('[') - if out.Avatars == nil { - if !in.IsDelim(']') { - out.Avatars = make(Avatars, 0, 8) - } else { - out.Avatars = Avatars{} - } - } else { - out.Avatars = (out.Avatars)[:0] - } - for !in.IsDelim(']') { - var v1 *CBAvatar - if in.IsNull() { - in.Skip() - v1 = nil - } else { - if v1 == nil { - v1 = new(CBAvatar) - } - (*v1).UnmarshalEasyJSON(in) - } - out.Avatars = append(out.Avatars, v1) - in.WantComma() - } - in.Delim(']') - } - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks3(out *jwriter.Writer, in CBGravatar) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"Avatars\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - if in.Avatars == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { - out.RawString("null") - } else { - out.RawByte('[') - for v2, v3 := range in.Avatars { - if v2 > 0 { - out.RawByte(',') - } - if v3 == nil { - out.RawString("null") - } else { - (*v3).MarshalEasyJSON(out) - } - } - out.RawByte(']') - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v CBGravatar) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks3(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v CBGravatar) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks3(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *CBGravatar) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks3(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *CBGravatar) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks3(l, v) -} -func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks4(in *jlexer.Lexer, out *CBGithub) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeString() - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "Followers": - out.Followers = int(in.Int()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks4(out *jwriter.Writer, in CBGithub) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"Followers\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.Int(int(in.Followers)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v CBGithub) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks4(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v CBGithub) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks4(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *CBGithub) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks4(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *CBGithub) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks4(l, v) -} -func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks5(in *jlexer.Lexer, out *CBAvatar) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeString() - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "Url": - out.Url = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks5(out *jwriter.Writer, in CBAvatar) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"Url\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.Url)) - } - out.RawByte('}') -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v CBAvatar) MarshalEasyJSON(w *jwriter.Writer) { - easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks5(w, v) -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *CBAvatar) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks5(l, v) -} diff --git a/benchmarks/benchmarks_small.go b/benchmarks/benchmarks_small.go @@ -1,76 +0,0 @@ -package benchmarks - -import "github.com/francoispqt/gojay" - -var SmallFixture = []byte(`{"st": 1,"sid": 486,"tt": "active","gr": 0,"uuid": "de305d54-75b4-431b-adb2-eb6b9e546014","ip": "127.0.0.1","ua": "user_agent","tz": -6,"v": 1}`) - -//easyjson:json -type SmallPayload struct { - St int - Sid int - Tt string - Gr int - Uuid string - Ip string - Ua string - Tz int - V int -} - -func (t *SmallPayload) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddIntKey("st", t.St) - enc.AddIntKey("sid", t.Sid) - enc.AddStringKey("tt", t.Tt) - enc.AddIntKey("gr", t.Gr) - enc.AddStringKey("uuid", t.Uuid) - enc.AddStringKey("ip", t.Ip) - enc.AddStringKey("ua", t.Ua) - enc.AddIntKey("tz", t.Tz) - enc.AddIntKey("v", t.V) -} - -func (t *SmallPayload) IsNil() bool { - return t == nil -} - -func (t *SmallPayload) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "st": - return dec.AddInt(&t.St) - case "sid": - return dec.AddInt(&t.Sid) - case "gr": - return dec.AddInt(&t.Gr) - case "tz": - return dec.AddInt(&t.Tz) - case "v": - return dec.AddInt(&t.V) - case "tt": - return dec.AddString(&t.Tt) - case "uuid": - return dec.AddString(&t.Uuid) - case "ip": - return dec.AddString(&t.Ip) - case "ua": - return dec.AddString(&t.Ua) - } - return nil -} - -func (t *SmallPayload) NKeys() int { - return 9 -} - -func NewSmallPayload() *SmallPayload { - return &SmallPayload{ - St: 1, - Sid: 2, - Tt: "TestString", - Gr: 4, - Uuid: "8f9a65eb-4807-4d57-b6e0-bda5d62f1429", - Ip: "127.0.0.1", - Ua: "Mozilla", - Tz: 8, - V: 6, - } -} diff --git a/benchmarks/benchmarks_small_easyjson.go b/benchmarks/benchmarks_small_easyjson.go @@ -1,186 +0,0 @@ -// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. - -package benchmarks - -import ( - json "encoding/json" - easyjson "github.com/mailru/easyjson" - jlexer "github.com/mailru/easyjson/jlexer" - jwriter "github.com/mailru/easyjson/jwriter" -) - -// suppress unused package warning -var ( - _ *json.RawMessage - _ *jlexer.Lexer - _ *jwriter.Writer - _ easyjson.Marshaler -) - -func easyjson890029d8DecodeGithubComFrancoispqtGojayBenchmarks(in *jlexer.Lexer, out *SmallPayload) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeString() - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "St": - out.St = int(in.Int()) - case "Sid": - out.Sid = int(in.Int()) - case "Tt": - out.Tt = string(in.String()) - case "Gr": - out.Gr = int(in.Int()) - case "Uuid": - out.Uuid = string(in.String()) - case "Ip": - out.Ip = string(in.String()) - case "Ua": - out.Ua = string(in.String()) - case "Tz": - out.Tz = int(in.Int()) - case "V": - out.V = int(in.Int()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson890029d8EncodeGithubComFrancoispqtGojayBenchmarks(out *jwriter.Writer, in SmallPayload) { - out.RawByte('{') - first := true - _ = first - { - const prefix string = ",\"St\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.Int(int(in.St)) - } - { - const prefix string = ",\"Sid\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.Int(int(in.Sid)) - } - { - const prefix string = ",\"Tt\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.Tt)) - } - { - const prefix string = ",\"Gr\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.Int(int(in.Gr)) - } - { - const prefix string = ",\"Uuid\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.Uuid)) - } - { - const prefix string = ",\"Ip\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.Ip)) - } - { - const prefix string = ",\"Ua\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.Ua)) - } - { - const prefix string = ",\"Tz\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.Int(int(in.Tz)) - } - { - const prefix string = ",\"V\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.Int(int(in.V)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v SmallPayload) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson890029d8EncodeGithubComFrancoispqtGojayBenchmarks(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v SmallPayload) MarshalEasyJSON(w *jwriter.Writer) { - easyjson890029d8EncodeGithubComFrancoispqtGojayBenchmarks(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *SmallPayload) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson890029d8DecodeGithubComFrancoispqtGojayBenchmarks(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *SmallPayload) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson890029d8DecodeGithubComFrancoispqtGojayBenchmarks(l, v) -} diff --git a/benchmarks/decoder/.gitignore b/benchmarks/decoder/.gitignore @@ -1 +0,0 @@ -vendor/* -\ No newline at end of file diff --git a/benchmarks/decoder/Makefile b/benchmarks/decoder/Makefile @@ -1,35 +0,0 @@ -.PHONY: test -test: - go test -run=^Test -v - -.PHONY: bench -bench: - go test -benchmem -run=^$ github.com/francoispqt/gojay/benchmarks/decoder -bench ^Benchmark - -.PHONY: benchtrace -benchtrace: - go test -c & GODEBUG=allocfreetrace=1 ./decoder.test -test.run=none -test.bench=^Benchmark -test.benchtime=10ms 2>trace.log - -.PHONY: benchcpu -benchcpu: - go test -benchmem -run=^$ github.com/francoispqt/gojay/benchmarks/decoder -bench ^Benchmark -cpuprofile cpu.out - -.PHONY: testtrace -testtrace: - go test -benchmem -run=^$ github.com/francoispqt/gojay/benchmarks/decoder -bench ^Benchmark -trace trace.out - -.PHONY: benchgojay -benchgojay: - go test -benchmem -run=^BenchmarkGoJay -bench=^BenchmarkGoJay -benchtime=30ms - -.PHONY: benchgojaycpu -benchgojaycpu: - go test -benchmem -run=^BenchmarkGoJay -bench=^BenchmarkGoJay -benchtime=30ms -cpuprofile cpu.out - -.PHONY: benchjsoniter -benchjsoniter: - go test -benchmem -run=^BenchmarkJsonIter -bench=^BenchmarkJsonIter -benchtime=30ms - -.PHONY: benchjsonparser -benchjsonparser: - go test -benchmem -run=^BenchmarkJsonParser -bench=^BenchmarkJsonParser -benchtime=30ms -\ No newline at end of file diff --git a/benchmarks/decoder/decoder.go b/benchmarks/decoder/decoder.go @@ -1 +0,0 @@ -package benchmarks diff --git a/benchmarks/decoder/decoder_bench_float_test.go b/benchmarks/decoder/decoder_bench_float_test.go @@ -1,28 +0,0 @@ -package benchmarks - -import ( - "encoding/json" - "testing" - - "github.com/francoispqt/gojay" -) - -var bigf = []byte(`0.00058273999999999999`) - -// BenchmarkBigFloatEncodingJSON decodes a big float with the standard package -func BenchmarkBigFloatEncodingJSON(b *testing.B) { - b.ReportAllocs() - for n := 0; n < b.N; n++ { - var f float64 - var _ = json.Unmarshal(bigf, &f) - } -} - -// BenchmarkBigFloatGojay decodes a big float with gojay -func BenchmarkBigFloatGojay(b *testing.B) { - b.ReportAllocs() - for n := 0; n < b.N; n++ { - var f float64 - var _ = gojay.Unmarshal(bigf, &f) - } -} diff --git a/benchmarks/decoder/decoder_bench_large_test.go b/benchmarks/decoder/decoder_bench_large_test.go @@ -1,59 +0,0 @@ -package benchmarks - -import ( - "testing" - - "github.com/buger/jsonparser" - "github.com/francoispqt/gojay" - "github.com/francoispqt/gojay/benchmarks" - jsoniter "github.com/json-iterator/go" - "github.com/mailru/easyjson" -) - -func BenchmarkJsonParserDecodeObjLarge(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - jsonparser.ArrayEach(benchmarks.LargeFixture, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { - jsonparser.Get(value, "username") - nothing() - }, "users") - - jsonparser.ArrayEach(benchmarks.LargeFixture, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { - jsonparser.GetInt(value, "id") - jsonparser.Get(value, "slug") - nothing() - }, "topics", "topics") - } -} - -func BenchmarkJsonIterDecodeObjLarge(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - result := benchmarks.LargePayload{} - jsoniter.Unmarshal(benchmarks.LargeFixture, &result) - } -} - -func BenchmarkEasyJsonDecodeObjLarge(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - result := benchmarks.LargePayload{} - easyjson.Unmarshal(benchmarks.LargeFixture, &result) - } -} - -func BenchmarkGoJayDecodeObjLarge(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - result := benchmarks.LargePayload{} - gojay.UnmarshalJSONObject(benchmarks.LargeFixture, &result) - } -} - -func BenchmarkGoJayUnsafeDecodeObjLarge(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - result := benchmarks.LargePayload{} - gojay.Unsafe.UnmarshalJSONObject(benchmarks.LargeFixture, &result) - } -} diff --git a/benchmarks/decoder/decoder_bench_medium_test.go b/benchmarks/decoder/decoder_bench_medium_test.go @@ -1,72 +0,0 @@ -package benchmarks - -import ( - "encoding/json" - "testing" - - "github.com/buger/jsonparser" - "github.com/francoispqt/gojay" - "github.com/francoispqt/gojay/benchmarks" - jsoniter "github.com/json-iterator/go" - "github.com/mailru/easyjson" -) - -func BenchmarkJsonIterDecodeObjMedium(b *testing.B) { - b.ReportAllocs() - for n := 0; n < b.N; n++ { - result := benchmarks.MediumPayload{} - jsoniter.Unmarshal(benchmarks.MediumFixture, &result) - } -} - -/* - github.com/buger/jsonparser -*/ -func BenchmarkJSONParserDecodeObjMedium(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - jsonparser.Get(benchmarks.MediumFixture, "person", "name", "fullName") - jsonparser.GetInt(benchmarks.MediumFixture, "person", "github", "followers") - jsonparser.Get(benchmarks.MediumFixture, "company") - - jsonparser.ArrayEach(benchmarks.MediumFixture, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { - jsonparser.Get(value, "url") - nothing() - }, "person", "gravatar", "avatars") - } -} - -func BenchmarkEncodingJsonStructMedium(b *testing.B) { - for i := 0; i < b.N; i++ { - var data = benchmarks.MediumPayload{} - json.Unmarshal(benchmarks.MediumFixture, &data) - } -} - -func BenchmarkEasyJsonDecodeObjMedium(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - result := benchmarks.MediumPayload{} - easyjson.Unmarshal(benchmarks.MediumFixture, &result) - } -} -func BenchmarkGoJayDecodeObjMedium(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - result := benchmarks.MediumPayload{} - err := gojay.UnmarshalJSONObject(benchmarks.MediumFixture, &result) - if err != nil { - b.Error(err) - } - } -} -func BenchmarkGoJayUnsafeDecodeObjMedium(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - result := benchmarks.MediumPayload{} - err := gojay.Unsafe.UnmarshalJSONObject(benchmarks.MediumFixture, &result) - if err != nil { - b.Error(err) - } - } -} diff --git a/benchmarks/decoder/decoder_bench_small_test.go b/benchmarks/decoder/decoder_bench_small_test.go @@ -1,69 +0,0 @@ -package benchmarks - -import ( - "encoding/json" - _ "fmt" - "testing" - - "github.com/buger/jsonparser" - "github.com/francoispqt/gojay" - "github.com/francoispqt/gojay/benchmarks" - jsoniter "github.com/json-iterator/go" - "github.com/mailru/easyjson" -) - -func BenchmarkJSONDecodeObjSmall(b *testing.B) { - b.ReportAllocs() - for n := 0; n < b.N; n++ { - result := benchmarks.SmallPayload{} - json.Unmarshal(benchmarks.SmallFixture, &result) - } -} - -func nothing(_ ...interface{}) {} -func BenchmarkJSONParserSmall(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - jsonparser.GetInt(benchmarks.SmallFixture, "tz") - jsonparser.GetInt(benchmarks.SmallFixture, "v") - jsonparser.GetInt(benchmarks.SmallFixture, "sid") - jsonparser.GetInt(benchmarks.SmallFixture, "st") - jsonparser.GetInt(benchmarks.SmallFixture, "gr") - jsonparser.Get(benchmarks.SmallFixture, "uuid") - jsonparser.Get(benchmarks.SmallFixture, "ua") - - nothing() - } -} - -func BenchmarkJsonIterDecodeObjSmall(b *testing.B) { - b.ReportAllocs() - for n := 0; n < b.N; n++ { - result := benchmarks.SmallPayload{} - jsoniter.Unmarshal(benchmarks.SmallFixture, &result) - } -} - -func BenchmarkEasyJsonDecodeObjSmall(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - result := benchmarks.SmallPayload{} - easyjson.Unmarshal(benchmarks.SmallFixture, &result) - } -} - -func BenchmarkGoJayDecodeObjSmall(b *testing.B) { - b.ReportAllocs() - for n := 0; n < b.N; n++ { - result := benchmarks.SmallPayload{} - gojay.UnmarshalJSONObject(benchmarks.SmallFixture, &result) - } -} - -func BenchmarkGoJayUnsafeDecodeObjSmall(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - result := benchmarks.SmallPayload{} - gojay.Unsafe.UnmarshalJSONObject(benchmarks.SmallFixture, &result) - } -} diff --git a/benchmarks/decoder/decoder_large_test.go b/benchmarks/decoder/decoder_large_test.go @@ -1,23 +0,0 @@ -package benchmarks - -import ( - "testing" - - "github.com/francoispqt/gojay" - "github.com/francoispqt/gojay/benchmarks" - "github.com/stretchr/testify/assert" -) - -func TestGoJayDecodeObjLarge(t *testing.T) { - result := benchmarks.LargePayload{} - err := gojay.UnmarshalJSONObject(benchmarks.LargeFixture, &result) - assert.Nil(t, err, "err should be nil") - assert.Len(t, result.Users, 32, "Len of users should be 32") - for _, u := range result.Users { - assert.True(t, len(u.Username) > 0, "User should have username") - } - assert.Len(t, result.Topics.Topics, 30, "Len of topics should be 30") - for _, top := range result.Topics.Topics { - assert.True(t, top.Id > 0, "Topic should have Id") - } -} diff --git a/benchmarks/decoder/decoder_medium_test.go b/benchmarks/decoder/decoder_medium_test.go @@ -1,18 +0,0 @@ -package benchmarks - -import ( - "testing" - - "github.com/francoispqt/gojay" - "github.com/francoispqt/gojay/benchmarks" - "github.com/stretchr/testify/assert" -) - -func TestGoJayDecodeObjMedium(t *testing.T) { - result := benchmarks.MediumPayload{} - err := gojay.Unmarshal(benchmarks.MediumFixture, &result) - assert.Nil(t, err, "err should be nil") - assert.Equal(t, "Leonid Bugaev", result.Person.Name.FullName, "result.Person.Name.FullName should be Leonid Bugaev") - assert.Equal(t, 95, result.Person.Github.Followers, "result.Person.Github.Followers should be 95") - assert.Len(t, result.Person.Gravatar.Avatars, 1, "result.Person.Gravatar.Avatars should have 1 item") -} diff --git a/benchmarks/decoder/decoder_small_test.go b/benchmarks/decoder/decoder_small_test.go @@ -1,29 +0,0 @@ -package benchmarks - -import ( - "testing" - - "github.com/francoispqt/gojay" - "github.com/francoispqt/gojay/benchmarks" - "github.com/stretchr/testify/assert" -) - -func TestGoJayDecodeObjSmall(t *testing.T) { - result := benchmarks.SmallPayload{} - err := gojay.Unmarshal(benchmarks.SmallFixture, &result) - assert.Nil(t, err, "err should be nil") - assert.Equal(t, result.St, 1, "result.St should be 1") - assert.Equal(t, result.Sid, 486, "result.Sid should be 486") - assert.Equal(t, result.Tt, "active", "result.Sid should be 'active'") - assert.Equal(t, result.Gr, 0, "result.Gr should be 0") - assert.Equal( - t, - result.Uuid, - "de305d54-75b4-431b-adb2-eb6b9e546014", - "result.Gr should be 'de305d54-75b4-431b-adb2-eb6b9e546014'", - ) - assert.Equal(t, result.Ip, "127.0.0.1", "result.Ip should be '127.0.0.1'") - assert.Equal(t, result.Ua, "user_agent", "result.Ua should be 'user_agent'") - assert.Equal(t, result.Tz, -6, "result.Tz should be 6") - assert.Equal(t, result.V, 1, "result.V should be 1") -} diff --git a/benchmarks/encoder/.gitignore b/benchmarks/encoder/.gitignore @@ -1 +0,0 @@ -vendor/* -\ No newline at end of file diff --git a/benchmarks/encoder/Makefile b/benchmarks/encoder/Makefile @@ -1,31 +0,0 @@ -.PHONY: bench -bench: - go test -benchmem -run=^$ github.com/francoispqt/gojay/benchmarks/encoder -bench ^Benchmark - -.PHONY: benchtrace -benchtrace: - go test -c & GODEBUG=allocfreetrace=1 ./encoder.test -test.run=none -test.bench=^Benchmark -test.benchtime=10ms 2>trace.log - -.PHONY: benchcpu -benchcpu: - go test -benchmem -run=^$ github.com/francoispqt/gojay/benchmarks/encoder -bench ^Benchmark -cpuprofile cpu.out - -.PHONY: testtrace -testtrace: - go test -benchmem -run=^$ github.com/francoispqt/gojay/benchmarks/encoder -bench ^Benchmark -trace trace.out - -.PHONY: benchgojay -benchgojay: - go test -benchmem -run=^BenchmarkGoJay -bench=^BenchmarkGoJay -benchtime=30ms - -.PHONY: benchgojaycpu -benchgojaycpu: - go test -benchmem -run=^BenchmarkGoJay -bench=^BenchmarkGoJay -benchtime=30ms -cpuprofile cpu.out - -.PHONY: benchjsoniter -benchjsoniter: - go test -benchmem -run=^BenchmarkJsonIter -bench=^BenchmarkJsonIter -benchtime=30ms - -.PHONY: benchjsonparser -benchjsonparser: - go test -benchmem -run=^BenchmarkJsonParser -bench=^BenchmarkJsonParser -benchtime=30ms -\ No newline at end of file diff --git a/benchmarks/encoder/encoder_bench_large_test.go b/benchmarks/encoder/encoder_bench_large_test.go @@ -1,56 +0,0 @@ -package benchmarks - -import ( - "encoding/json" - "log" - "testing" - - "github.com/francoispqt/gojay" - "github.com/francoispqt/gojay/benchmarks" - jsoniter "github.com/json-iterator/go" - "github.com/mailru/easyjson" -) - -func BenchmarkEncodingJsonEncodeLargeStruct(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := json.Marshal(benchmarks.NewLargePayload()); err != nil { - b.Fatal(err) - } - } -} -func BenchmarkJsonIterEncodeLargeStruct(b *testing.B) { - var json = jsoniter.ConfigCompatibleWithStandardLibrary - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := json.Marshal(benchmarks.NewLargePayload()); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkEasyJsonEncodeObjLarge(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := easyjson.Marshal(benchmarks.NewLargePayload()); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkGoJayEncodeLargeStruct(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := gojay.MarshalJSONObject(benchmarks.NewLargePayload()); err != nil { - b.Fatal(err) - } - } -} - -func TestGoJayEncodeLargeStruct(t *testing.T) { - if output, err := gojay.MarshalJSONObject(benchmarks.NewLargePayload()); err != nil { - t.Fatal(err) - } else { - log.Print(string(output)) - } -} diff --git a/benchmarks/encoder/encoder_bench_medium_test.go b/benchmarks/encoder/encoder_bench_medium_test.go @@ -1,57 +0,0 @@ -package benchmarks - -import ( - "encoding/json" - "log" - "testing" - - "github.com/francoispqt/gojay" - "github.com/francoispqt/gojay/benchmarks" - jsoniter "github.com/json-iterator/go" - "github.com/mailru/easyjson" -) - -func BenchmarkEncodingJsonEncodeMediumStruct(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := json.Marshal(benchmarks.NewMediumPayload()); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkJsonIterEncodeMediumStruct(b *testing.B) { - var json = jsoniter.ConfigCompatibleWithStandardLibrary - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := json.Marshal(benchmarks.NewMediumPayload()); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkEasyJsonEncodeObjMedium(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := easyjson.Marshal(benchmarks.NewMediumPayload()); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkGoJayEncodeMediumStruct(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := gojay.MarshalJSONObject(benchmarks.NewMediumPayload()); err != nil { - b.Fatal(err) - } - } -} - -func TestGoJayEncodeMediumStruct(t *testing.T) { - if output, err := gojay.MarshalJSONObject(benchmarks.NewMediumPayload()); err != nil { - t.Fatal(err) - } else { - log.Print(string(output)) - } -} diff --git a/benchmarks/encoder/encoder_bench_small_test.go b/benchmarks/encoder/encoder_bench_small_test.go @@ -1,76 +0,0 @@ -package benchmarks - -import ( - "encoding/json" - "log" - "testing" - - "github.com/francoispqt/gojay" - "github.com/francoispqt/gojay/benchmarks" - jsoniter "github.com/json-iterator/go" - "github.com/mailru/easyjson" -) - -func BenchmarkEncodingJsonEncodeSmallStruct(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := json.Marshal(benchmarks.NewSmallPayload()); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkEasyJsonEncodeObjSmall(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := easyjson.Marshal(benchmarks.NewSmallPayload()); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkJsonIterEncodeSmallStruct(b *testing.B) { - var json = jsoniter.ConfigCompatibleWithStandardLibrary - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := json.Marshal(benchmarks.NewSmallPayload()); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkGoJayEncodeSmallStruct(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := gojay.MarshalJSONObject(benchmarks.NewSmallPayload()); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkGoJayEncodeSmallFunc(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := gojay.MarshalJSONObject(gojay.EncodeObjectFunc(func(enc *gojay.Encoder) { - enc.AddIntKey("st", 1) - enc.AddIntKey("sid", 1) - enc.AddStringKey("tt", "test") - enc.AddIntKey("gr", 1) - enc.AddStringKey("uuid", "test") - enc.AddStringKey("ip", "test") - enc.AddStringKey("ua", "test") - enc.AddIntKey("tz", 1) - enc.AddIntKey("v", 1) - })); err != nil { - b.Fatal(err) - } - } -} - -func TestGoJayEncodeSmallStruct(t *testing.T) { - if output, err := gojay.MarshalJSONObject(benchmarks.NewSmallPayload()); err != nil { - t.Fatal(err) - } else { - log.Print(output) - } -} diff --git a/benchmarks/encoder/encoder_large_test.go b/benchmarks/encoder/encoder_large_test.go @@ -1 +0,0 @@ -package benchmarks diff --git a/benchmarks/encoder/encoder_medium_test.go b/benchmarks/encoder/encoder_medium_test.go @@ -1 +0,0 @@ -package benchmarks diff --git a/benchmarks/encoder/encoder_small_test.go b/benchmarks/encoder/encoder_small_test.go @@ -1 +0,0 @@ -package benchmarks diff --git a/decode_example_test.go b/decode_example_test.go @@ -5,7 +5,7 @@ import ( "log" "strings" - "github.com/francoispqt/gojay" + "go.lair.cx/gojay" ) func ExampleUnmarshal_string() { diff --git a/encode_example_test.go b/encode_example_test.go @@ -5,7 +5,7 @@ import ( "log" "os" - "github.com/francoispqt/gojay" + "go.lair.cx/gojay" ) func ExampleMarshal_string() { diff --git a/examples/encode-decode-map/main.go b/examples/encode-decode-map/main.go @@ -1,100 +0,0 @@ -package main - -import ( - "log" - "strings" - - "github.com/francoispqt/gojay" -) - -// define our custom map type implementing MarshalerJSONObject and UnmarshalerJSONObject -type myMap map[string]string - -// Implementing Unmarshaler -func (m myMap) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - str := "" - err := dec.AddString(&str) - if err != nil { - return err - } - m[k] = str - return nil -} - -// Her we put the number of keys -// If number of keys is unknown return 0, it will parse all keys -func (m myMap) NKeys() int { - return 0 -} - -// Implementing Marshaler -func (m myMap) MarshalJSONObject(enc *gojay.Encoder) { - for k, v := range m { - enc.AddStringKey(k, v) - } -} - -func (m myMap) IsNil() bool { - return m == nil -} - -// Using Marshal / Unmarshal API -func marshalAPI(m myMap) error { - b, err := gojay.Marshal(m) - if err != nil { - return err - } - log.Print(string(b)) - - nM := myMap(make(map[string]string)) - err = gojay.Unmarshal(b, nM) - if err != nil { - return err - } - log.Print(nM) - return nil -} - -// Using Encode / Decode API -func encodeAPI(m myMap) error { - // we use strings.Builder as it implements io.Writer - builder := &strings.Builder{} - enc := gojay.BorrowEncoder(builder) - defer enc.Release() - // encode - err := enc.EncodeObject(m) - if err != nil { - return err - } - log.Print(builder.String()) - - // make our new map which will receive the decoded JSON - nM := myMap(make(map[string]string)) - // get our decoder with an io.Reader - dec := gojay.BorrowDecoder(strings.NewReader(builder.String())) - defer dec.Release() - // decode - err = dec.DecodeObject(nM) - if err != nil { - return err - } - log.Print(nM) - return nil -} - -func main() { - // make our map to be encoded - m := myMap(map[string]string{ - "test": "test", - "test2": "test2", - }) - - err := marshalAPI(m) - if err != nil { - log.Fatal(err) - } - err = encodeAPI(m) - if err != nil { - log.Fatal(err) - } -} diff --git a/examples/fuzz/Makefile b/examples/fuzz/Makefile @@ -1,11 +0,0 @@ -.PHONY: gofuzzbuild -gofuzzbuild: - go-fuzz-build github.com/francoispqt/gojay/examples/fuzz - -.PHONY: gofuzz -gofuzz: - go-fuzz -bin=fuzz-fuzz.zip -workdir=. - -.PHONY: gofuzzclean -gofuzzclean: - rm -rf corpus crashers suppressions fuzz-fuzz.zip -\ No newline at end of file diff --git a/examples/fuzz/main.go b/examples/fuzz/main.go @@ -1,46 +0,0 @@ -package fuzz - -import ( - "github.com/francoispqt/gojay" -) - -type user struct { - id int - created uint64 - age float64 - name string - email string - friend *user -} - -// implement gojay.UnmarshalerJSONObject -func (u *user) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "id": - return dec.Int(&u.id) - case "created": - return dec.Uint64(&u.created) - case "age": - return dec.Float(&u.age) - case "name": - return dec.String(&u.name) - case "email": - return dec.String(&u.email) - case "friend": - uu := &user{} - return dec.Object(uu) - } - return nil -} -func (u *user) NKeys() int { - return 3 -} - -func Fuzz(input []byte) int { - u := &user{} - err := gojay.UnmarshalJSONObject(input, u) - if err != nil { - return 0 - } - return 1 -} diff --git a/examples/http-benchmarks/Makefile b/examples/http-benchmarks/Makefile @@ -1,4 +0,0 @@ - -.PHONY: bench -bench: - wrk -d 20s -s post.lua http://localhost:3000 -\ No newline at end of file diff --git a/examples/http-benchmarks/README.md b/examples/http-benchmarks/README.md @@ -1,52 +0,0 @@ -# HTTP BENCHMARKS - -This package has two different implementation of a basic HTTP server in Go. It just takes a JSON body, unmarshals it and marshals it back to the response. - -It required `wrk` benchmarking tool, which you can find here: https://github.com/wg/wrk - -## How to run - -### gojay -```bash -cd /path/to/package && go run gojay/main.go -``` -Then run: -```bash -cd /path/to/package && make bench -``` - -### standard package (encoding/json) -```bash -cd /path/to/package && go run standard/main.go -``` -Then run: -```bash -cd /path/to/package && make bench -``` - -## Results - -Results presented here are ran on a MacBook Pro Mid 2015 2,2 GHz Intel Core i7 with 16G of RAM - -**gojay results:** -``` -Running 20s test @ http://localhost:3000 - 2 threads and 10 connections - Thread Stats Avg Stdev Max +/- Stdev - Latency 298.77us 341.40us 10.52ms 94.13% - Req/Sec 18.88k 1.89k 21.40k 73.63% - 755246 requests in 20.10s, 1.67GB read -Requests/sec: 37573.84 -Transfer/sec: 84.85MB -``` -**standard results:** -``` -Running 20s test @ http://localhost:3000 - 2 threads and 10 connections - Thread Stats Avg Stdev Max +/- Stdev - Latency 613.21us 557.50us 12.65ms 93.88% - Req/Sec 9.18k 423.20 10.10k 80.50% - 365404 requests in 20.00s, 811.60MB read -Requests/sec: 18269.66 -Transfer/sec: 40.58MB -``` -\ No newline at end of file diff --git a/examples/http-benchmarks/gojay/main.go b/examples/http-benchmarks/gojay/main.go @@ -1,158 +0,0 @@ -package main - -import ( - "log" - "net/http" - - "github.com/francoispqt/gojay" -) - -func main() { - log.Println("Listening on port 3000") - log.Fatal(http.ListenAndServe(":3000", http.HandlerFunc(handler))) -} - -func handler(w http.ResponseWriter, r *http.Request) { - var body Body - dec := gojay.BorrowDecoder(r.Body) - defer dec.Release() - err := dec.Decode(&body) - if err != nil { - panic(err) - } - w.Header().Set("Content-Type", "application/json") - enc := gojay.BorrowEncoder(w) - defer enc.Release() - err = enc.Encode(&body) - if err != nil { - panic(err) - } -} - -type Body struct { - Colors *colors `json:"colors"` -} - -func (c *Body) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - switch k { - case "colors": - cols := make(colors, 0) - c.Colors = &cols - return dec.Array(c.Colors) - } - return nil -} -func (b *Body) NKeys() int { - return 1 -} - -func (b *Body) MarshalJSONObject(enc *gojay.Encoder) { - enc.ArrayKey("colors", b.Colors) -} -func (b *Body) IsNil() bool { - return b == nil -} - -type colors []*Color - -func (b *colors) UnmarshalJSONArray(dec *gojay.Decoder) error { - color := &Color{} - if err := dec.Object(color); err != nil { - return err - } - *b = append(*b, color) - return nil -} - -func (b *colors) MarshalJSONArray(enc *gojay.Encoder) { - for _, color := range *b { - enc.Object(color) - } -} - -func (b *colors) IsNil() bool { - return len(*b) == 0 -} - -type Color struct { - Color string `json:"color,omitempty"` - Category string `json:"category,omitempty"` - Type string `json:"type,omitempty"` - Code *Code `json:"code,omitempty"` -} - -func (b *Color) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - switch k { - case "color": - return dec.String(&b.Color) - case "category": - return dec.String(&b.Category) - case "type": - return dec.String(&b.Type) - case "code": - b.Code = &Code{} - return dec.Object(b.Code) - } - return nil -} -func (b *Color) NKeys() int { - return 4 -} - -func (b *Color) MarshalJSONObject(enc *gojay.Encoder) { - enc.ObjectKey("code", b.Code) - enc.StringKey("color", b.Color) - enc.StringKey("category", b.Category) - enc.StringKey("type", b.Type) -} -func (b *Color) IsNil() bool { - return b == nil -} - -type Code struct { - RGBA *ints `json:"rgba,omitempty"` - Hex string `json:"hex,omitempty"` -} - -func (c *Code) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - switch k { - case "rgba": - rgba := make(ints, 0) - c.RGBA = &rgba - return dec.Array(&rgba) - case "hex": - return dec.String(&c.Hex) - } - return nil -} -func (b *Code) NKeys() int { - return 2 -} - -func (b *Code) MarshalJSONObject(enc *gojay.Encoder) { - enc.ArrayKey("rgba", b.RGBA) - enc.StringKey("hex", b.Hex) -} -func (b *Code) IsNil() bool { - return b == nil -} - -type ints []int - -func (v *ints) UnmarshalJSONArray(dec *gojay.Decoder) error { - var i int - if err := dec.Int(&i); err != nil { - return err - } - *v = append(*v, i) - return nil -} - -func (v *ints) MarshalJSONArray(enc *gojay.Encoder) { - for _, i := range *v { - enc.Int(i) - } -} -func (v *ints) IsNil() bool { - return v == nil || len(*v) == 0 -} diff --git a/examples/http-benchmarks/post.lua b/examples/http-benchmarks/post.lua @@ -1,220 +0,0 @@ -wrk.method = "POST" -wrk.body = [=[ - { - "colors": [ - { - "color": "black", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,255,255,1], - "hex": "#000" - } - }, - { - "color": "white", - "category": "value", - "code": { - "rgba": [0,0,0,1], - "hex": "#FFF" - } - }, - { - "color": "red", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,0,0,1], - "hex": "#FF0" - } - }, - { - "color": "blue", - "category": "hue", - "type": "primary", - "code": { - "rgba": [0,0,255,1], - "hex": "#00F" - } - }, - { - "color": "yellow", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,255,0,1], - "hex": "#FF0" - } - }, - { - "color": "green", - "category": "hue", - "type": "secondary", - "code": { - "rgba": [0,255,0,1], - "hex": "#0F0" - } - }, - { - "color": "black", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,255,255,1], - "hex": "#000" - } - }, - { - "color": "white", - "category": "value", - "code": { - "rgba": [0,0,0,1], - "hex": "#FFF" - } - }, - { - "color": "red", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,0,0,1], - "hex": "#FF0" - } - }, - { - "color": "blue", - "category": "hue", - "type": "primary", - "code": { - "rgba": [0,0,255,1], - "hex": "#00F" - } - }, - { - "color": "yellow", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,255,0,1], - "hex": "#FF0" - } - }, - { - "color": "green", - "category": "hue", - "type": "secondary", - "code": { - "rgba": [0,255,0,1], - "hex": "#0F0" - } - }, - { - "color": "black", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,255,255,1], - "hex": "#000" - } - }, - { - "color": "white", - "category": "value", - "code": { - "rgba": [0,0,0,1], - "hex": "#FFF" - } - }, - { - "color": "red", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,0,0,1], - "hex": "#FF0" - } - }, - { - "color": "blue", - "category": "hue", - "type": "primary", - "code": { - "rgba": [0,0,255,1], - "hex": "#00F" - } - }, - { - "color": "yellow", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,255,0,1], - "hex": "#FF0" - } - }, - { - "color": "green", - "category": "hue", - "type": "secondary", - "code": { - "rgba": [0,255,0,1], - "hex": "#0F0" - } - }, - { - "color": "black", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,255,255,1], - "hex": "#000" - } - }, - { - "color": "white", - "category": "value", - "code": { - "rgba": [0,0,0,1], - "hex": "#FFF" - } - }, - { - "color": "red", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,0,0,1], - "hex": "#FF0" - } - }, - { - "color": "blue", - "category": "hue", - "type": "primary", - "code": { - "rgba": [0,0,255,1], - "hex": "#00F" - } - }, - { - "color": "yellow", - "category": "hue", - "type": "primary", - "code": { - "rgba": [255,255,0,1], - "hex": "#FF0" - } - }, - { - "color": "green", - "category": "hue", - "type": "secondary", - "code": { - "rgba": [0,255,0,1], - "hex": "#0F0" - } - } - ] - } -]=] -wrk.headers["Content-Type"] = "application/json" diff --git a/examples/http-benchmarks/standard/main.go b/examples/http-benchmarks/standard/main.go @@ -1,42 +0,0 @@ -package main - -import ( - "encoding/json" - "log" - "net/http" -) - -func main() { - log.Println("Listening on port 3000") - log.Fatal(http.ListenAndServe(":3000", http.HandlerFunc(handler))) -} - -func handler(w http.ResponseWriter, r *http.Request) { - var body Body - err := json.NewDecoder(r.Body).Decode(&body) - if err != nil { - panic(err) - } - - w.Header().Set("Content-Type", "application/json") - err = json.NewEncoder(w).Encode(body) - if err != nil { - panic(err) - } -} - -type Body struct { - Colors []Color `json:"colors"` -} - -type Color struct { - Color string `json:"color,omitempty"` - Category string `json:"category,omitempty"` - Type string `json:"type,omitempty"` - Code Code `json:"code,omitempty"` -} - -type Code struct { - RGBA []int `json:"rgba,omitempty"` - Hex string `json:"hex,omitempty"` -} diff --git a/examples/http-json/main.go b/examples/http-json/main.go @@ -1,72 +0,0 @@ -package main - -import ( - "net/http" - - "github.com/francoispqt/gojay" -) - -type message struct { - foo string - bar string -} - -func (m *message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - switch k { - case "foo": - return dec.AddString(&m.foo) - case "bar": - return dec.AddString(&m.bar) - } - return nil -} - -func (m *message) NKeys() int { - return 2 -} - -func (m *message) MarshalJSONObject(dec *gojay.Encoder) { - dec.AddStringKey("foo", m.foo) - dec.AddStringKey("bar", m.bar) -} - -func (m *message) IsNil() bool { - return m == nil -} - -func home(w http.ResponseWriter, r *http.Request) { - // read body using io.Reader - m := &message{} - dec := gojay.BorrowDecoder(r.Body) - defer dec.Release() - err := dec.DecodeObject(m) - if err != nil { - i, err := w.Write([]byte(err.Error())) - if err != nil || i == 0 { - panic(err) - } - return - } - - // just transform response slightly - m.foo += "hey" - - // return response using io.Writer - enc := gojay.BorrowEncoder(w) - defer enc.Release() - err = enc.Encode(m) - if err != nil { - i, err := w.Write([]byte(err.Error())) - if err != nil || i == 0 { - panic(err) - } - } - return -} - -func main() { - http.HandleFunc("/", home) - if err := http.ListenAndServe(":8080", nil); err != nil { - panic(err) - } -} diff --git a/examples/websocket/client/client.go b/examples/websocket/client/client.go @@ -1,27 +0,0 @@ -package client - -import ( - "github.com/francoispqt/gojay/examples/websocket/comm" - "golang.org/x/net/websocket" -) - -type client struct { - comm.SenderReceiver - id int -} - -func NewClient(id int) *client { - c := new(client) - c.id = id - return c -} - -func (c *client) Dial(url, origin string) error { - conn, err := websocket.Dial(url, "", origin) - if err != nil { - return err - } - c.Conn = conn - c.Init(10) - return nil -} diff --git a/examples/websocket/comm/comm.go b/examples/websocket/comm/comm.go @@ -1,107 +0,0 @@ -package comm - -import ( - "errors" - "log" - - "github.com/francoispqt/gojay" - "golang.org/x/net/websocket" -) - -// A basic message for our WebSocket app - -type Message struct { - Message string - UserName string -} - -func (m *Message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - switch k { - case "message": - return dec.AddString(&m.Message) - case "userName": - return dec.AddString(&m.UserName) - } - return nil -} -func (m *Message) NKeys() int { - return 2 -} - -func (m *Message) MarshalJSONObject(enc *gojay.Encoder) { - enc.AddStringKey("message", m.Message) - enc.AddStringKey("userName", m.UserName) -} -func (u *Message) IsNil() bool { - return u == nil -} - -// Here are defined our communication types -type Sender chan gojay.MarshalerJSONObject - -func (s Sender) MarshalStream(enc *gojay.StreamEncoder) { - select { - case <-enc.Done(): - return - case m := <-s: - enc.AddObject(m) - } -} - -type Receiver chan *Message - -func (s Receiver) UnmarshalStream(dec *gojay.StreamDecoder) error { - m := &Message{} - if err := dec.AddObject(m); err != nil { - return err - } - s <- m - return nil -} - -type SenderReceiver struct { - Send Sender - Receive Receiver - Dec *gojay.StreamDecoder - Enc *gojay.StreamEncoder - Conn *websocket.Conn -} - -func (sc *SenderReceiver) SetReceiver() { - sc.Receive = Receiver(make(chan *Message)) - sc.Dec = gojay.Stream.BorrowDecoder(sc.Conn) - go sc.Dec.DecodeStream(sc.Receive) -} - -func (sc *SenderReceiver) SetSender(nCons int) { - sc.Send = Sender(make(chan gojay.MarshalerJSONObject)) - sc.Enc = gojay.Stream.BorrowEncoder(sc.Conn).NConsumer(nCons).LineDelimited() - go sc.Enc.EncodeStream(sc.Send) -} - -func (sc *SenderReceiver) SendMessage(m gojay.MarshalerJSONObject) error { - select { - case <-sc.Enc.Done(): - return errors.New("sender closed") - case sc.Send <- m: - log.Print("message sent by client: ", m) - return nil - } -} - -func (c *SenderReceiver) OnMessage(f func(*Message)) error { - for { - select { - case <-c.Dec.Done(): - return errors.New("receiver closed") - case m := <-c.Receive: - f(m) - } - } -} - -func (sc *SenderReceiver) Init(sender int) *SenderReceiver { - sc.SetSender(sender) - sc.SetReceiver() - return sc -} diff --git a/examples/websocket/main.go b/examples/websocket/main.go @@ -1,75 +0,0 @@ -// package main simulates a conversation between -// a given set of websocket clients and a server. -// -// It spins up a web socket server. -// On a client's connection it creates a SenderReceiver which handles JSON Stream -// encoding and decoding using gojay's streaming API to abstract JSON communication -// between server and client, only having to handle go values. -// -// To simulate a conversation: -// - the server sends a welcome message to the client -// - when the client receives the message, it sends a message back to the server -// - when the server receives the ack message, it will send a message randomly to a client -// - when the client receives the message, it sends a message back to the server... and so on. -package main - -import ( - "log" - "strconv" - - "github.com/francoispqt/gojay/examples/websocket/client" - "github.com/francoispqt/gojay/examples/websocket/comm" - "github.com/francoispqt/gojay/examples/websocket/server" -) - -func createServer(done chan error) { - // create our server, with a done signal - s := server.NewServer() - // set our connection handler - s.OnConnection(func(c *server.Client) { - // send welcome message to initiate the conversation - c.SendMessage(&comm.Message{ - UserName: "server", - Message: "Welcome !", - }) - // start handling messages - c.OnMessage(func(m *comm.Message) { - log.Print("message received from client: ", m) - s.BroadCastRandom(c, m) - }) - }) - go s.Listen(":8070", done) -} - -func createClient(url, origin string, i int) { - // create our client - c := client.NewClient(i) - // Dial connection to the WS server - err := c.Dial(url, origin) - if err != nil { - panic(err) - } - str := strconv.Itoa(i) - // Init client's sender and receiver - // Set the OnMessage handler - c.OnMessage(func(m *comm.Message) { - log.Print("client "+str+" received from "+m.UserName+" message: ", m) - c.SendMessage(&comm.Message{ - UserName: str, - Message: "Responding to: " + m.UserName + " | old message: " + m.Message, - }) - }) -} - -// Our main function -func main() { - done := make(chan error) - createServer(done) - // add our clients connection - for i := 0; i < 100; i++ { - i := i - go createClient("ws://localhost:8070/ws", "http://localhost/", i) - } - // handle server's termination - log.Fatal(<-done) -} diff --git a/examples/websocket/server/server.go b/examples/websocket/server/server.go @@ -1,82 +0,0 @@ -package server - -import ( - "log" - "math/rand" - "net/http" - "sync" - "time" - - "github.com/francoispqt/gojay/examples/websocket/comm" - "golang.org/x/net/websocket" -) - -type server struct { - clients []*Client - mux *sync.RWMutex - handle func(c *Client) -} - -type Client struct { - comm.SenderReceiver - server *server -} - -func NewClient(s *server, conn *websocket.Conn) *Client { - sC := new(Client) - sC.Conn = conn - sC.server = s - return sC -} - -func NewServer() *server { - s := new(server) - s.mux = new(sync.RWMutex) - s.clients = make([]*Client, 0, 100) - return s -} - -func (c *Client) Close() { - c.Conn.Close() -} - -func (s *server) Handle(conn *websocket.Conn) { - defer func() { - err := conn.Close() - if err != nil { - log.Fatal(err) - } - }() - c := NewClient(s, conn) - // add our server client to the list of clients - s.mux.Lock() - s.clients = append(s.clients, c) - s.mux.Unlock() - // init Client's sender and receiver - c.Init(10) - s.handle(c) - // block until reader is done - <-c.Dec.Done() -} - -func (s *server) Listen(port string, done chan error) { - http.Handle("/ws", websocket.Handler(s.Handle)) - done <- http.ListenAndServe(port, nil) -} - -func (s *server) OnConnection(h func(c *Client)) { - s.handle = h -} - -func random(min, max int) int { - rand.Seed(time.Now().Unix()) - return rand.Intn(max-min) + min -} - -func (s *server) BroadCastRandom(sC *Client, m *comm.Message) { - m.Message = "Random message" - s.mux.RLock() - r := random(0, len(s.clients)) - s.clients[r].SendMessage(m) - s.mux.RUnlock() -} diff --git a/go.mod b/go.mod @@ -1,24 +1,11 @@ -module github.com/francoispqt/gojay +module go.lair.cx/gojay -go 1.12 +go 1.19 + +require github.com/stretchr/testify v1.8.0 require ( - cloud.google.com/go v0.37.0 // indirect - github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 - github.com/go-errors/errors v1.0.1 - github.com/golang/protobuf v1.3.1 // indirect - github.com/json-iterator/go v1.1.6 - github.com/lunixbochs/vtclean v1.0.0 // indirect - github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect - github.com/pkg/errors v0.8.1 // indirect - github.com/stretchr/testify v1.2.2 - github.com/viant/assertly v0.4.8 - github.com/viant/toolbox v0.24.0 - golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a // indirect - golang.org/x/net v0.0.0-20190313220215-9f648a60d977 - golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 // indirect - golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f // indirect - gopkg.in/yaml.v2 v2.2.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum @@ -1,182 +1,15 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.0 h1:69FNAINiZfsEuwH3fKq8QrAAnHz+2m4XL4kVYi5BX0Q= -cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI= -github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8= -github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe h1:W/GaMY0y69G4cFlmsC6B9sbuo2fP8OFP1ABjt4kPz+w= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/viant/assertly v0.4.8 h1:5x1GzBaRteIwTr5RAGFVG14uNeRFxVNbXPWrK2qAgpc= -github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= -github.com/viant/toolbox v0.24.0 h1:6TteTDQ68CjgcCe8wH3D3ZhUQQOJXMTbj/D9rkk2a1k= -github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a h1:YX8ljsm6wXlHZO+aRz9Exqr0evNhKRNe5K/gi+zKh4U= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977 h1:actzWV6iWn3GLqN8dZjzsB+CLt+gaV2+wsxroxiQI8I= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f h1:yCrMx/EeIue0+Qca57bWZS7VX6ymEoypmhWyPhz0NHM= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/gojay/README.md b/gojay/README.md @@ -1,61 +0,0 @@ -# Gojay code generator -This package provides a command line tool to generate gojay's marshaling and unmarshaling interface implementation for custom struct type(s) - - -## Get started - -```sh -go install github.com/francoispqt/gojay/gojay -``` - -## Generate code - -### Basic command -The basic command is straightforward and easy to use: -```sh -cd $GOPATH/src/github.com/user/project -gojay -s . -p true -t MyType -o output.go -``` -If you just want to the output to stdout, omit the -o flag. - -### Using flags -- s Source file/dir path, can be a relative or absolute path -- t Types to generate with all its dependencies (comma separated) -- a Annotation tag used to read metadata (default: json) -- o Output file (relative or absolute path) -- p Pool to reuse object (using sync.Pool) - -Examples: - -- Generate `SomeType` type in `/tmp/myproj` go package, write to file `output.go`: -```sh -gojay -s /tmp/myproj -t SomeType -o output.go -``` - -- Generate type `SomeType` in file `somegofile.go`, with custom tag `gojay`, write to stdout: -```sh -gojay -s somegofile.go -a gojay -t SomeType -``` - - -## Generator tags -You can add tags to your structs to control: - -- the JSON key -- skip a struct field -- the use of omitempty methods for marshaling -- timeFormat (java style data format) -- timeLayout (golang time layout) - - -### Example: -```go -type A struct { - Str string `json:"string"` - StrOmitEmpty string `json:"stringOrEmpty,omitempty"` - Skip string `json:"-"` - StartTime time.Time `json:"startDate" timeFormat:"yyyy-MM-dd HH:mm:ss"` - EndTime *time.Time `json:"endDate" timeLayout:"2006-01-02 15:04:05"` -} -``` - diff --git a/gojay/codegen/field.go b/gojay/codegen/field.go @@ -1,168 +0,0 @@ -package codegen - -import ( - "fmt" - "github.com/viant/toolbox" - "strings" -) - -//Field represents a field. -type Field struct { - Key string - Init string - OmitEmpty string - TimeLayout string - NullType string - Name string - Accessor string - Mutator string - Receiver string //alias and type name - Alias string //object alias name - Var string //variable for this field - Type string - RawType string - HelperType string - ComponentType string - RawComponentType string - IsPointerComponent bool - - PointerModifier string //takes field pointer, "&" if field is not a pointer type - DereferenceModifier string //take pointer value, i.e "*" if field has a pointer type - - ComponentPointerModifier string //takes item pointer if needed,i.e - ComponentDereferenceModifier string //de reference value if needed, i.e - ComponentInitModifier string //takes item pointer if type is not a pointer type - ComponentInit string //initialises component type - - DecodingMethod string - EncodingMethod string - PoolName string //pool name associated with this field - ResetDependency string - Reset string - IsAnonymous bool - IsPointer bool - IsSlice bool - - GojayMethod string -} - -//NewField returns a new field -func NewField(owner *Struct, field *toolbox.FieldInfo, fieldType *toolbox.TypeInfo) (*Field, error) { - typeName := normalizeTypeName(field.TypeName) - var result = &Field{ - IsAnonymous: field.IsAnonymous, - Name: field.Name, - RawType: field.TypeName, - IsPointer: field.IsPointer, - Key: getJSONKey(owner.options, field), - Receiver: owner.Alias + " *" + owner.TypeInfo.Name, - Type: typeName, - Mutator: owner.Alias + "." + field.Name, - Accessor: owner.Alias + "." + field.Name, - ComponentType: field.ComponentType, - IsPointerComponent: field.IsPointerComponent, - Var: firstLetterToLowercase(field.Name), - Init: fmt.Sprintf("%v{}", typeName), - TimeLayout: "time.RFC3339", - IsSlice: field.IsSlice, - PoolName: getPoolName(field.TypeName), - Alias: owner.Alias, - Reset: "nil", - } - var err error - if field.IsPointer { - result.DereferenceModifier = "*" - result.Init = "&" + result.Init - } else { - result.PointerModifier = "&" - - } - if field.IsSlice { - result.HelperType = getSliceHelperTypeName(field.ComponentType, field.IsPointerComponent) - result.PoolName = getPoolName(field.ComponentType) - } else if fieldType != nil { - result.HelperType = getSliceHelperTypeName(fieldType.Name, field.IsPointerComponent) - } - - if options := getTagOptions(field.Tag, "timeLayout"); len(options) > 0 { - result.TimeLayout = wrapperIfNeeded(options[0], `"`) - } else if options := getTagOptions(field.Tag, "timeFormat"); len(options) > 0 { - result.TimeLayout = wrapperIfNeeded(toolbox.DateFormatToLayout(options[0]), `"`) - } - if strings.Contains(field.Tag, "omitempty") { - result.OmitEmpty = "OmitEmpty" - } - if strings.Contains(field.Tag, "nullempty") { - result.OmitEmpty = "NullEmpty" - } - - if owner.options.PoolObjects { - if field.IsPointer && !strings.HasSuffix(field.TypeName, ".Time") && !strings.Contains(field.TypeName, "sql.Null") { - poolName := getPoolName(field.TypeName) - result.Init = fmt.Sprintf(`%v.Get().(*%v)`, poolName, field.TypeName) - } - } - - encodingMethod := field.ComponentType - if encodingMethod == "" { - encodingMethod = result.Type - } - result.DecodingMethod = firstLetterToUppercase(encodingMethod) - result.EncodingMethod = firstLetterToUppercase(encodingMethod) - - switch typeName { - case "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64": - result.Reset = "0" - case "float32", "float64": - result.Reset = "0.0" - case "string": - result.Reset = `""` - - case "bool": - result.Reset = "false" - default: - if field.IsSlice && owner.Type(field.ComponentType) != nil { - var itemPointer = "" - if !field.IsPointerComponent { - itemPointer = "&" - } - result.ResetDependency, err = expandFieldTemplate(poolSliceInstanceRelease, struct { - PoolName string - Accessor string - PointerModifier string - }{PoolName: result.PoolName, Accessor: result.Accessor, PointerModifier: itemPointer}) - if err != nil { - return nil, err - } - - } else if field.IsPointer && fieldType != nil { - result.ResetDependency, err = expandFieldTemplate(poolInstanceRelease, struct { - PoolName string - Accessor string - }{PoolName: result.PoolName, Accessor: result.Accessor}) - if err != nil { - return nil, err - } - } - - } - if field.IsSlice || field.IsPointer { - result.Reset = "nil" - } - - if result.IsPointerComponent { - result.ComponentInit = "&" + result.ComponentType + "{}" - result.RawComponentType = "*" + result.ComponentType - - result.ComponentDereferenceModifier = "*" - result.ComponentInitModifier = "&" - - } else { - result.ComponentInit = result.ComponentType + "{}" - result.RawComponentType = result.ComponentType - - result.ComponentPointerModifier = "&" - } - - return result, nil -} diff --git a/gojay/codegen/generator.go b/gojay/codegen/generator.go @@ -1,255 +0,0 @@ -package codegen - -import ( - "fmt" - "go/format" - "io/ioutil" - "os" - "path/filepath" - "strings" - "github.com/viant/toolbox" -) - -const gojayPackage = "github.com/francoispqt/gojay" - -// Generator holds the content to generate the gojay code -type Generator struct { - fileInfo *toolbox.FileSetInfo - types map[string]string - structTypes map[string]string - sliceTypes map[string]string - pooledObjects map[string]string - poolInit map[string]string - imports map[string]bool - filedInit []string - Pkg string - Code string - Init string - Imports string - options *Options -} - -// Returns the type from the the fileInfo -func (g *Generator) Type(typeName string) *toolbox.TypeInfo { - return g.fileInfo.Type(typeName) -} - -// addImport adds an import package to be printed on the generated code -func (g *Generator) addImport(pkg string) { - g.imports[`"`+pkg+`"`] = true -} - -// we initiate the variables containing the code to be generated -func (g *Generator) init() { - g.filedInit = []string{} - g.imports = map[string]bool{} - g.pooledObjects = map[string]string{} - g.structTypes = map[string]string{} - g.sliceTypes = map[string]string{} - g.poolInit = map[string]string{} - g.addImport(gojayPackage) - // if we want pools, add the sync package right away - if g.options.PoolObjects { - g.addImport("sync") - } -} - -// NewGenerator creates a new generator with the given options -func NewGenerator(options *Options) *Generator { - var g = &Generator{} - // first we validate the flags - if err := options.Validate(); err != nil { - panic(err) - } - g.options = options - // we initiate the values on the generator - g.init() - return g -} - -// Generate generates the gojay implementation code -func (g *Generator) Generate() error { - // first we read the code from which we should find the types - if err := g.readPackageCode(g.options.Source); err != nil { - return err - } - - // then we generate code for the types given - for _, rootType := range g.options.Types { - if err := g.generateStructCode(rootType); err != nil { - return err - } - } - - // - g.Imports = strings.Join(toolbox.MapKeysToStringSlice(g.imports), "\n") - return g.writeCode() -} - -func (g *Generator) writeCode() error { - var generatedCode = []string{} - - for _, key := range sortedKeys(g.pooledObjects) { - code := g.pooledObjects[key] - generatedCode = append(generatedCode, code) - } - generatedCode = append(generatedCode, "") - for _, key := range sortedKeys(g.sliceTypes) { - code := g.sliceTypes[key] - generatedCode = append(generatedCode, code) - } - generatedCode = append(generatedCode, "") - for _, key := range sortedKeys(g.structTypes) { - code := g.structTypes[key] - generatedCode = append(generatedCode, code) - } - - for _, key := range sortedKeys(g.poolInit) { - code := g.poolInit[key] - if g.Init != "" { - g.Init += "\n" - } - g.Init += code - } - g.Code = strings.Join(generatedCode, "\n") - - expandedCode, err := expandBlockTemplate(fileCode, g) - if err != nil { - return err - } - - code, err := format.Source([]byte(expandedCode)) - - if err != nil { - return err - } - - // code destination is empty, we just print to stdout - if g.options.Dest == "" { - fmt.Print(string(code)) - return nil - } - - return ioutil.WriteFile(g.options.Dest, code, 0644) -} - -func (g *Generator) generatePrimitiveArray(field *Field) error { - key := field.ComponentType + toolbox.AsString(field.IsPointerComponent) - if _, ok := g.sliceTypes[key]; ok { - return nil - } - code, err := expandBlockTemplate(baseTypeSlice, field) - g.sliceTypes[key] = code - return err -} - -func (g *Generator) generateObjectArray(field *Field) error { - if _, ok := g.sliceTypes[field.RawComponentType]; ok { - return nil - } - - if err := g.generateStructCode(field.ComponentType); err != nil { - return err - } - code, err := expandBlockTemplate(structTypeSlice, field) - if err != nil { - return err - } - g.sliceTypes[field.RawComponentType] = code - return err -} - -func (g *Generator) generateTimeArray(field *Field) error { - if _, ok := g.sliceTypes[field.RawComponentType]; ok { - return nil - } - - code, err := expandBlockTemplate(timeSlice, field) - if err != nil { - return err - } - g.sliceTypes[field.RawComponentType] = code - return err -} - -func (g *Generator) generateTypedArray(field *Field) error { - if _, ok := g.sliceTypes[field.RawComponentType]; ok { - return nil - } - - code, err := expandBlockTemplate(typeSlice, field) - if err != nil { - return err - } - g.sliceTypes[field.RawComponentType] = code - return err -} - -func (g *Generator) generatePool(structType string) error { - if !g.options.PoolObjects { - return nil - } - var err error - if g.pooledObjects[structType], err = expandBlockTemplate(poolVar, struct { - PoolName string - }{getPoolName(structType)}); err == nil { - g.poolInit[structType], err = expandBlockTemplate(poolInit, struct { - PoolName string - Type string - }{getPoolName(structType), structType}) - } - return err - -} - -func (g *Generator) generateStructCode(structType string) error { - structType = normalizeTypeName(structType) - typeInfo := g.Type(structType) - if typeInfo == nil { - return nil - } - if _, hasCode := g.structTypes[structType]; hasCode { - return nil - } - g.generatePool(structType) - - aStruct := NewStruct(typeInfo, g) - code, err := aStruct.Generate() - - if err != nil { - return err - } - - g.structTypes[structType] = code - return nil -} - -func (g *Generator) readPackageCode(pkgPath string) error { - p, err := filepath.Abs(pkgPath) - if err != nil { - return err - } - - var f os.FileInfo - if f, err = os.Stat(p); err != nil { - // path/to/whatever does not exist - return err - } - - if !f.IsDir() { - g.Pkg = filepath.Dir(p) - dir, _ := filepath.Split(p) - g.fileInfo, err = toolbox.NewFileSetInfo(dir) - - } else { - g.Pkg = filepath.Base(p) - g.fileInfo, err = toolbox.NewFileSetInfo(p) - } - - // if Pkg flag is set use it - if g.options.Pkg != "" { - g.Pkg = g.options.Pkg - } - - return err -} diff --git a/gojay/codegen/generator_test.go b/gojay/codegen/generator_test.go @@ -1,72 +0,0 @@ -package codegen - -import ( - "github.com/stretchr/testify/assert" - "github.com/viant/toolbox" - "log" - "path" - "testing" -) - -func TestGenerator_Generate(t *testing.T) { - - parent := path.Join(toolbox.CallerDirectory(3), "test") - - var useCases = []struct { - description string - options *Options - hasError bool - }{ - { - description: "basic struct code generation", - options: &Options{ - Source: path.Join(parent, "basic_struct"), - Types: []string{"Message"}, - Dest: path.Join(parent, "basic_struct", "encoding.go"), - }, - }, - - { - description: "struct with pool code generation", - options: &Options{ - Source: path.Join(parent, "pooled_struct"), - Types: []string{"Message"}, - Dest: path.Join(parent, "pooled_struct", "encoding.go"), - PoolObjects: true, - }, - }, - { - description: "struct with embedded type code generation", - options: &Options{ - Source: path.Join(parent, "embedded_struct"), - Types: []string{"Message"}, - Dest: path.Join(parent, "embedded_struct", "encoding.go"), - PoolObjects: false, - }, - }, - { - description: "struct with json annotation and time/foarmat|layouat generation", - options: &Options{ - Source: path.Join(parent, "annotated_struct"), - Types: []string{"Message"}, - Dest: path.Join(parent, "annotated_struct", "encoding.go"), - PoolObjects: false, - TagName: "json", - }, - }, - } - - for _, useCase := range useCases { - gen := NewGenerator(useCase.options) - err := gen.Generate() - if useCase.hasError { - assert.NotNil(t, err, useCase.description) - continue - } - if !assert.Nil(t, err, useCase.description) { - log.Fatal(err) - continue - } - } - -} diff --git a/gojay/codegen/helper.go b/gojay/codegen/helper.go @@ -1,101 +0,0 @@ -package codegen - -import ( - "github.com/viant/toolbox" - "reflect" - "strings" - "sort" -) - -func firstLetterToUppercase(text string) string { - return strings.ToUpper(string(text[0:1])) + string(text[1:]) -} - -func firstLetterToLowercase(text string) string { - return strings.ToLower(string(text[0:1])) + string(text[1:]) -} - -func extractReceiverAlias(structType string) string { - var result = string(structType[0]) - for i := len(structType) - 1; i > 0; i-- { - aChar := string(structType[i]) - lowerChar := strings.ToLower(aChar) - if lowerChar != aChar { - result = lowerChar - break - } - } - return strings.ToLower(result) -} - -func getTagOptions(tag, key string) []string { - if tag == "" { - return nil - } - var structTag = reflect.StructTag(strings.Replace(tag, "`", "", len(tag))) - options, ok := structTag.Lookup(key) - if !ok { - return nil - } - return strings.Split(options, ",") -} - -func getSliceHelperTypeName(typeName string, isPointer bool) string { - if typeName == "" { - return "" - } - - var pluralName = firstLetterToUppercase(typeName) + "s" - if isPointer { - pluralName += "Ptr" - } - return strings.Replace(pluralName, ".", "", -1) -} - -func isSkipable(options *Options, field *toolbox.FieldInfo) bool { - if options := getTagOptions(field.Tag, options.TagName); len(options) > 0 { - for _, candidate := range options { - if candidate == "-" { - return true - } - } - } - return false -} - -func wrapperIfNeeded(text, wrappingChar string) string { - if strings.HasPrefix(text, wrappingChar) { - return text - } - return wrappingChar + text + wrappingChar -} - -func getPoolName(typeName string) string { - typeName = strings.Replace(typeName, "*", "", 1) - return strings.Replace(typeName+"Pool", ".", "", -1) -} - -func getJSONKey(options *Options, field *toolbox.FieldInfo) string { - var key = field.Name - if field.Tag != "" { - if options := getTagOptions(field.Tag, options.TagName); len(options) > 0 { - key = options[0] - } - } - return key -} - -func normalizeTypeName(typeName string) string { - return strings.Replace(typeName, "*", "", strings.Count(typeName, "*")) -} - -func sortedKeys(m map[string]string) ([]string) { - keys := make([]string, len(m)) - i := 0 - for k := range m { - keys[i] = k - i++ - } - sort.Strings(keys) - return keys -} -\ No newline at end of file diff --git a/gojay/codegen/options.go b/gojay/codegen/options.go @@ -1,55 +0,0 @@ -package codegen - -import ( - "flag" - "strings" - - "github.com/go-errors/errors" - "github.com/viant/toolbox" - "github.com/viant/toolbox/url" -) - -type Options struct { - Source string - Dest string - Types []string - PoolObjects bool - TagName string - Pkg string -} - -func (o *Options) Validate() error { - if o.Source == "" { - return errors.New("Source was empty") - } - if len(o.Types) == 0 { - return errors.New("Types was empty") - } - return nil -} - -const ( - optionKeySource = "s" - optionKeyDest = "o" - optionKeyTypes = "t" - optionKeyTagName = "a" - optionKeyPoolObjects = "p" - optionKeyPkg = "pkg" -) - -//NewOptionsWithFlagSet creates a new options for the supplide flagset -func NewOptionsWithFlagSet(set *flag.FlagSet) *Options { - toolbox.Dump(set) - - var result = &Options{} - result.Dest = set.Lookup(optionKeyDest).Value.String() - result.Source = set.Lookup(optionKeySource).Value.String() - result.PoolObjects = toolbox.AsBoolean(set.Lookup(optionKeyPoolObjects).Value.String()) - result.TagName = set.Lookup(optionKeyTagName).Value.String() - result.Types = strings.Split(set.Lookup(optionKeyTypes).Value.String(), ",") - result.Pkg = set.Lookup(optionKeyPkg).Value.String() - if result.Source == "" { - result.Source = url.NewResource(".").ParsedURL.Path - } - return result -} diff --git a/gojay/codegen/struct.go b/gojay/codegen/struct.go @@ -1,345 +0,0 @@ -package codegen - -import ( - "fmt" - "strings" - - "github.com/viant/toolbox" -) - -type Struct struct { - *toolbox.TypeInfo - referenced *toolbox.TypeInfo - *Generator - Alias string - Init string - Body string -} - -//Generate generates decoderCode + structRelease + encoderCode -func (s *Struct) Generate() (string, error) { - return s.generateEncoding(s.TypeInfo) -} - -func (s *Struct) generateEncoding(structInfo *toolbox.TypeInfo) (string, error) { - var initEmbedded, decodingCases, err = s.generateFieldDecoding(structInfo.Fields()) - if err != nil { - return "", err - } - - encodingCases, err := s.generateFieldEncoding(structInfo.Fields()) - if err != nil { - return "", err - } - var resetCode = "" - if s.options.PoolObjects { - resetCode, err = s.generateReset(structInfo.Fields()) - if err != nil { - return "", err - } - } - var data = struct { - Receiver string - Alias string - InitEmbedded string - EncodingCases string - DecodingCases string - Reset string - FieldCount int - }{ - Receiver: s.Alias + " *" + s.Name, - DecodingCases: strings.Join(decodingCases, "\n"), - EncodingCases: strings.Join(encodingCases, "\n"), - FieldCount: len(decodingCases), - InitEmbedded: initEmbedded, - Reset: resetCode, - Alias: s.Alias, - } - return expandBlockTemplate(encodingStructType, data) -} - -func (s *Struct) generateReset(fields []*toolbox.FieldInfo) (string, error) { - fieldReset, err := s.generateFieldReset(fields) - if err != nil { - return "", nil - } - return expandBlockTemplate(resetStruct, struct { - Reset string - Receiver string - }{ - Reset: strings.Join(fieldReset, "\n"), - Receiver: s.Alias + " *" + s.Name, - }) -} - -func (s *Struct) generateFieldReset(fields []*toolbox.FieldInfo) ([]string, error) { - fieldReset := []string{} - for i := range fields { - var templateKey = -1 - fieldTypeInfo := s.Type(normalizeTypeName(fields[i].TypeName)) - field, err := NewField(s, fields[i], fieldTypeInfo) - if err != nil { - return nil, err - } - if field.IsPointer || field.IsSlice || (fieldTypeInfo != nil && fieldTypeInfo.IsSlice) { - templateKey = resetFieldValue - } else { - switch field.Type { - case "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64", "string", "bool", "[]string", "[]bool", "[]int", "[]int8", "[]int16", "[]int32", "[]int64", "[]uint", "[]uint8", "[]uint16", "[]uint32", "[]uint64", "[]float32", "[]float64", "[]byte": - templateKey = resetFieldValue - } - } - if templateKey != -1 { - code, err := expandFieldTemplate(templateKey, field) - if err != nil { - return nil, err - } - fieldReset = append(fieldReset, code) - } - } - return fieldReset, nil -} - -func (s *Struct) generateFieldDecoding(fields []*toolbox.FieldInfo) (string, []string, error) { - - fieldCases := []string{} - var initCode = "" - for i := range fields { - if isSkipable(s.options, fields[i]) { - continue - } - var templateKey = -1 - fieldTypeInfo := s.Type(normalizeTypeName(fields[i].TypeName)) - field, err := NewField(s, fields[i], fieldTypeInfo) - if err != nil { - return "", nil, err - } - if fieldTypeInfo != nil { - if err = s.generateStructCode(fieldTypeInfo.Name); err != nil { - return "", nil, err - } - } - - if field.IsAnonymous { - if fieldTypeInfo != nil { - if field.IsPointer { - init, err := expandBlockTemplate(embeddedStructInit, field) - if err != nil { - return "", nil, err - } - initCode += init - } - init, embeddedCases, err := s.generateFieldDecoding(fieldTypeInfo.Fields()) - if err != nil { - return "", nil, err - } - initCode += init - fieldCases = append(fieldCases, embeddedCases...) - } - continue - } - - main: - switch field.Type { - case "string", "bool", "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64": - templateKey = decodeBaseType - case "[]string", "[]bool", "[]int", "[]int8", "[]int16", "[]int32", "[]int64", "[]uint", "[]uint8", "[]uint16", "[]uint32", "[]uint64", "[]float32", "[]float64": - templateKey = decodeBaseTypeSlice - s.generatePrimitiveArray(field) - case "[]byte": - templateKey = decodeRawType - default: - - if fieldTypeInfo != nil { - if !(field.IsSlice || fieldTypeInfo.IsSlice) { - - templateKey = decodeStruct - break main - } - - switch fieldTypeInfo.ComponentType { - case "byte": - templateKey = decodeRawType - break main - - case "string", "bool", "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64": - s.generatePrimitiveArray(field) - templateKey = decodeBaseTypeSlice - break main - - } - - if err = s.generateStructCode(field.ComponentType); err != nil { - return "", nil, err - } - - templateKey = decodeStructSlice - if err = s.generateObjectArray(field); err != nil { - return "", nil, err - } - - break main - } else if field.IsSlice { - if f, _, ok := s.typedFieldDecode(field, field.ComponentType); ok { - templateKey = decodeStructSlice - if err = f(field); err != nil { - return "", nil, err - } - } else { - templateKey = decodeStructSlice - if err = s.generateObjectArray(field); err != nil { - return "", nil, err - } - } - } else if _, k, ok := s.typedFieldDecode(field, field.Type); ok { - templateKey = k - } else { - // templateKey = decodeUnknown - return "", nil, fmt.Errorf("Unknown type %s for field %s", field.Type, field.Name) - } - } - if templateKey != -1 { - decodingCase, err := expandFieldTemplate(templateKey, field) - if err != nil { - return "", nil, err - } - fieldCases = append(fieldCases, decodingCase) - } - - } - return initCode, fieldCases, nil -} - -func (s *Struct) generateEmbeddedFieldEncoding(field *Field, fieldTypeInfo *toolbox.TypeInfo) ([]string, error) { - var result = []string{} - if fieldTypeInfo != nil { - embeddedCases, err := s.generateFieldEncoding(fieldTypeInfo.Fields()) - if err != nil { - return nil, err - } - if field.IsPointer { - result = append(result, fmt.Sprintf(" if %v != nil {", field.Accessor)) - for _, code := range embeddedCases { - result = append(result, " "+code) - } - result = append(result, " }") - } else { - result = append(result, embeddedCases...) - } - } - return result, nil -} - -func (s *Struct) generateFieldEncoding(fields []*toolbox.FieldInfo) ([]string, error) { - fieldCases := []string{} - for i := range fields { - if isSkipable(s.options, fields[i]) { - continue - } - var templateKey = -1 - fieldTypeInfo := s.Type(normalizeTypeName(fields[i].TypeName)) - field, err := NewField(s, fields[i], fieldTypeInfo) - if err != nil { - return nil, err - } - if field.IsAnonymous { - embedded, err := s.generateEmbeddedFieldEncoding(field, fieldTypeInfo) - if err != nil { - return nil, err - } - fieldCases = append(fieldCases, embedded...) - continue - } - main: - switch field.Type { - case "string", "bool", "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64": - templateKey = encodeBaseType - case "[]string", "[]bool", "[]int", "[]int8", "[]int16", "[]int32", "[]int64", "[]uint", "[]uint8", "[]uint16", "[]uint32", "[]uint64", "[]float32", "[]float64": - templateKey = encodeBaseTypeSlice - s.generatePrimitiveArray(field) - case "[]byte": - templateKey = encodeRawType - default: - if fieldTypeInfo != nil { - if !(field.IsSlice || fieldTypeInfo.IsSlice) { - templateKey = encodeStruct - break main - } - switch fieldTypeInfo.ComponentType { - case "byte": - templateKey = encodeRawType - break main - case "string", "bool", "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64": - templateKey = decodeBaseTypeSlice - break main - } - templateKey = encodeStructSlice - break main - } else if field.IsSlice { - templateKey = encodeStructSlice - } else if _, k, ok := s.typedFieldEncode(field, field.Type); ok { - templateKey = k - } else { - // templateKey = decodeUnknown - return nil, fmt.Errorf("Unknown type %s for field %s", field.Type, field.Name) - } - } - if templateKey != -1 { - decodingCase, err := expandFieldTemplate(templateKey, field) - if err != nil { - return nil, err - } - fieldCases = append(fieldCases, decodingCase) - } - - } - return fieldCases, nil -} - -var sqlNullTypes = []string{ - "Bool", - "Float64", - "Int64", - "String", - "Time", -} - -func (s *Struct) typedFieldEncode(field *Field, typeName string) (func(*Field) error, int, bool) { - if strings.Contains(typeName, "time.Time") { - return s.generateTimeArray, encodeTime, true - } else if strings.Contains(typeName, "sql.Null") { - for _, nullType := range sqlNullTypes { - if strings.Contains(typeName, nullType) { - field.NullType = nullType - field.GojayMethod = "SQLNull" + nullType - } - } - return s.generateTypedArray, encodeSQLNull, true - } - return nil, 0, false -} - -func (s *Struct) typedFieldDecode(field *Field, typeName string) (func(*Field) error, int, bool) { - if strings.Contains(typeName, "time.Time") { - s.addImport("time") - return s.generateTimeArray, decodeTime, true - } else if strings.Contains(typeName, "sql.Null") { - for _, nullType := range sqlNullTypes { - if strings.Contains(typeName, nullType) { - field.NullType = nullType - field.GojayMethod = "SQLNull" + nullType - } - } - s.addImport("database/sql") - return s.generateTypedArray, decodeSQLNull, true - } - return nil, 0, false -} - -func NewStruct(info *toolbox.TypeInfo, generator *Generator) *Struct { - return &Struct{ - TypeInfo: info, - Generator: generator, - Alias: extractReceiverAlias(info.Name), - } -} diff --git a/gojay/codegen/template.go b/gojay/codegen/template.go @@ -1,321 +0,0 @@ -package codegen - -import ( - "bytes" - "fmt" - "text/template" -) - -const ( - decodeBaseType = iota - encodeBaseType - decodeBaseTypeSlice - encodeBaseTypeSlice - decodeRawType - encodeRawType - decodeStruct - encodeStruct - - decodeStructSlice - encodeStructSlice - decodeTime - encodeTime - - decodeSQLNull - encodeSQLNull - - decodeUnknown - encodeUnknown - - resetFieldValue - poolInstanceRelease - poolSliceInstanceRelease -) - -var fieldTemplate = map[int]string{ - decodeBaseType: ` case "{{.Key}}": -{{if .IsPointer}} var value {{.Type}} - err := dec.{{.DecodingMethod}}(&value) - if err == nil { - {{.Accessor}} = &value - } - return err -{{else}} return dec.{{.DecodingMethod}}(&{{.Accessor}}){{end}} -`, - encodeBaseType: ` enc.{{.EncodingMethod}}Key{{.OmitEmpty}}("{{.Key}}", {{.DereferenceModifier}}{{.Accessor}})`, - - decodeBaseTypeSlice: ` case "{{.Key}}": - var aSlice = {{.HelperType}}{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - {{.Mutator}} = {{.RawType}}(aSlice) - } - return err -`, - encodeBaseTypeSlice: ` var {{.Var}}Slice = {{.HelperType}}({{.Accessor}}) - enc.ArrayKey{{.OmitEmpty}}("{{.Key}}",{{.Var}}Slice)`, - - decodeRawType: ` case "{{.Key}}": - var value = gojay.EmbeddedJSON{} - err := dec.AddEmbeddedJSON(&value) - if err == nil && len(value) > 0 { - {{.Mutator}} = {{.Type}}(value) - } - return err -`, - - encodeRawType: ` var {{.Var}}Slice = gojay.EmbeddedJSON({{.Accessor}}) - enc.AddEmbeddedJSONKey{{.OmitEmpty}}("{{.Key}}", &{{.Var}}Slice)`, - decodeStruct: ` case "{{.Key}}":{{if .IsPointer}} - var value = {{.Init}} - err := dec.Object(value) - if err == nil { - {{.Mutator}} = value - } -{{else}} - err := dec.Object(&{{.Mutator}}) -{{end}} - return err -`, - encodeStruct: ` enc.ObjectKey{{.OmitEmpty}}("{{.Key}}", {{.PointerModifier}}{{.Accessor}})`, - - decodeStructSlice: ` case "{{.Key}}": - var aSlice = {{.HelperType}}{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - {{.Mutator}} = {{.RawType}}(aSlice) - } - return err - `, - - encodeStructSlice: ` var {{.Var}}Slice = {{.HelperType}}({{.Accessor}}) - enc.ArrayKey{{.OmitEmpty}}("{{.Key}}", {{.DereferenceModifier}}{{.Var}}Slice)`, - - decodeTime: ` case "{{.Key}}": - var format = {{.TimeLayout}} - var value = {{.Init}} - err := dec.Time({{.PointerModifier}}value, format) - if err == nil { - {{.Mutator}} = value - } - return err -`, - - encodeTime: `{{if .IsPointer}} if {{.Accessor}} != nil { - enc.TimeKey("{{.Key}}", {{.PointerModifier}}{{.Accessor}}, {{.TimeLayout}}) - }{{else}} enc.TimeKey("{{.Key}}", {{.PointerModifier}}{{.Accessor}}, {{.TimeLayout}}){{end}}`, - decodeSQLNull: ` case "{{.Key}}": - var value = {{.Init}} - err := dec.SQLNull{{.NullType}}({{.PointerModifier}}value) - if err == nil { - {{.Mutator}} = value - } - return err -`, - encodeSQLNull: `{{if .IsPointer}} if {{.Accessor}} != nil { - enc.SQLNull{{.NullType}}Key{{.OmitEmpty}}("{{.Key}}", {{.PointerModifier}}{{.Accessor}}) - }{{else}} enc.SQLNull{{.NullType}}Key{{.OmitEmpty}}("{{.Key}}", {{.PointerModifier}}{{.Accessor}}){{end}}`, - decodeUnknown: ` case "{{.Key}}": - return dec.Any({{.PointerModifier}}{{.Accessor}}) -`, - encodeUnknown: `{{if .IsPointer}} if {{.Accessor}} != nil { - enc.Any({{.Accessor}}) - }{{else}}enc.Any({{.Accessor}}){{end}}`, - resetFieldValue: `{{if .ResetDependency}}{{.ResetDependency}} -{{end}} {{.Mutator}} = {{.Reset}}`, - poolInstanceRelease: ` {{.PoolName}}.Put({{.Accessor}})`, - - poolSliceInstanceRelease: ` for i := range {{.Accessor}} { - {{.Accessor}}[i].Reset() - {{.PoolName}}.Put({{.PointerModifier}}{{.Accessor}}[i]) - }`, -} - -const ( - fileCode = iota - encodingStructType - baseTypeSlice - structTypeSlice - resetStruct - poolVar - poolInit - embeddedStructInit - timeSlice - typeSlice -) - -var blockTemplate = map[int]string{ - fileCode: `// Code generated by Gojay. DO NOT EDIT. - - -package {{.Pkg}} - -import ( - {{.Imports}} -) -{{if .Init}} -func init() { -{{.Init}} -} -{{end}} -{{.Code}} -`, - encodingStructType: `// MarshalJSONObject implements MarshalerJSONObject -func ({{.Receiver}}) MarshalJSONObject(enc *gojay.Encoder) { -{{.EncodingCases}} -} - -// IsNil checks if instance is nil -func ({{.Receiver}}) IsNil() bool { - return {{.Alias}} == nil -} - -// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject -func ({{.Receiver}}) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { -{{.InitEmbedded}} - switch k { -{{.DecodingCases}} - } - return nil -} - -// NKeys returns the number of keys to unmarshal -func ({{.Receiver}}) NKeys() int { return {{.FieldCount}} } - -{{.Reset}} - -`, - - baseTypeSlice: ` - -type {{.HelperType}} {{.RawType}} - -// UnmarshalJSONArray decodes JSON array elements into slice -func (a *{{.HelperType}}) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value {{.ComponentType}} - if err := dec.{{.DecodingMethod}}(&value); err != nil { - return err - } - *a = append(*a, {{.ComponentInitModifier}}value) - return nil -} - -// MarshalJSONArray encodes arrays into JSON -func (a {{.HelperType}}) MarshalJSONArray(enc *gojay.Encoder) { - for _, item := range a { - enc.{{.EncodingMethod}}({{.ComponentDereferenceModifier}}item) - } -} - -// IsNil checks if array is nil -func (a {{.HelperType}}) IsNil() bool { - return len(a) == 0 -} -`, - - structTypeSlice: ` -type {{.HelperType}} {{.RawType}} - -func (s *{{.HelperType}}) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value = {{.ComponentInit}} - if err := dec.Object({{.ComponentPointerModifier}}value); err != nil { - return err - } - *s = append(*s, value) - return nil -} - -func (s {{.HelperType}}) MarshalJSONArray(enc *gojay.Encoder) { - for i := range s { - enc.Object({{.ComponentPointerModifier}}s[i]) - } -} - -func (s {{.HelperType}}) IsNil() bool { - return len(s) == 0 -} -`, - typeSlice: ` -type {{.HelperType}} {{.RawType}} - -func (s *{{.HelperType}}) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value = {{.ComponentInit}} - if err := dec.{{.GojayMethod}}({{.ComponentPointerModifier}}value); err != nil { - return err - } - *s = append(*s, value) - return nil -} - -func (s {{.HelperType}}) MarshalJSONArray(enc *gojay.Encoder) { - for i := range s { - enc.{{.GojayMethod}}({{.ComponentPointerModifier}}s[i]) - } -} - -func (s {{.HelperType}}) IsNil() bool { - return len(s) == 0 -} -`, - timeSlice: ` -type {{.HelperType}} {{.RawType}} - -func (s *{{.HelperType}}) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value = {{.ComponentInit}} - if err := dec.Time({{.ComponentPointerModifier}}value, {{.TimeLayout}}); err != nil { - return err - } - *s = append(*s, value) - return nil -} - -func (s {{.HelperType}}) MarshalJSONArray(enc *gojay.Encoder) { - for i := range s { - enc.Time({{.ComponentPointerModifier}}s[i], {{.TimeLayout}}) - } -} - -func (s {{.HelperType}}) IsNil() bool { - return len(s) == 0 -} -`, - resetStruct: ` -// Reset reset fields -func ({{.Receiver}}) Reset() { -{{.Reset}} -} -`, - - poolVar: `var {{.PoolName}} *sync.Pool`, - poolInit: ` {{.PoolName}} = &sync.Pool { - New: func()interface{} { - return &{{.Type}}{} - }, - }`, - embeddedStructInit: `if {{.Accessor}} == nil { - {{.Accessor}} = {{.Init}} - }`, -} - -func expandTemplate(namespace string, dictionary map[int]string, key int, data interface{}) (string, error) { - var id = fmt.Sprintf("%v_%v", namespace, key) - textTemplate, ok := dictionary[key] - if !ok { - return "", fmt.Errorf("failed to lookup template for %v.%v", namespace, key) - } - temlate, err := template.New(id).Parse(textTemplate) - if err != nil { - return "", fmt.Errorf("fiailed to parse template %v %v, due to %v", namespace, key, err) - } - writer := new(bytes.Buffer) - err = temlate.Execute(writer, data) - return writer.String(), err -} - -func expandFieldTemplate(key int, data interface{}) (string, error) { - return expandTemplate("fieldTemplate", fieldTemplate, key, data) -} - -func expandBlockTemplate(key int, data interface{}) (string, error) { - return expandTemplate("blockTemplate", blockTemplate, key, data) -} diff --git a/gojay/codegen/template_test.go b/gojay/codegen/template_test.go @@ -1,19 +0,0 @@ -package codegen - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func Test_ExpandTemplate(t *testing.T) { - var dictionary = map[int]string{ - 1: `type {{.TypeName}} {{.SourceTypeName}}`, - } - expaded, err := expandTemplate("test", dictionary, 1, struct { - TypeName string - SourceTypeName string - }{"A", "B"}) - - assert.Nil(t, err) - assert.Equal(t, "type A B", expaded) -} diff --git a/gojay/codegen/test/annotated_struct/encoding.go b/gojay/codegen/test/annotated_struct/encoding.go @@ -1,289 +0,0 @@ -// Code generated by Gojay. DO NOT EDIT. - -package annotated_struct - -import ( - "database/sql" - "github.com/francoispqt/gojay" - "time" -) - -type Ints []int - -// UnmarshalJSONArray decodes JSON array elements into slice -func (a *Ints) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value int - if err := dec.Int(&value); err != nil { - return err - } - *a = append(*a, value) - return nil -} - -// MarshalJSONArray encodes arrays into JSON -func (a Ints) MarshalJSONArray(enc *gojay.Encoder) { - for _, item := range a { - enc.Int(item) - } -} - -// IsNil checks if array is nil -func (a Ints) IsNil() bool { - return len(a) == 0 -} - -type Float32s []float32 - -// UnmarshalJSONArray decodes JSON array elements into slice -func (a *Float32s) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value float32 - if err := dec.Float32(&value); err != nil { - return err - } - *a = append(*a, value) - return nil -} - -// MarshalJSONArray encodes arrays into JSON -func (a Float32s) MarshalJSONArray(enc *gojay.Encoder) { - for _, item := range a { - enc.Float32(item) - } -} - -// IsNil checks if array is nil -func (a Float32s) IsNil() bool { - return len(a) == 0 -} - -type SubMessagesPtr []*SubMessage - -func (s *SubMessagesPtr) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value = &SubMessage{} - if err := dec.Object(value); err != nil { - return err - } - *s = append(*s, value) - return nil -} - -func (s SubMessagesPtr) MarshalJSONArray(enc *gojay.Encoder) { - for i := range s { - enc.Object(s[i]) - } -} - -func (s SubMessagesPtr) IsNil() bool { - return len(s) == 0 -} - -type SubMessages []SubMessage - -func (s *SubMessages) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value = SubMessage{} - if err := dec.Object(&value); err != nil { - return err - } - *s = append(*s, value) - return nil -} - -func (s SubMessages) MarshalJSONArray(enc *gojay.Encoder) { - for i := range s { - enc.Object(&s[i]) - } -} - -func (s SubMessages) IsNil() bool { - return len(s) == 0 -} - -// MarshalJSONObject implements MarshalerJSONObject -func (p *Payload) MarshalJSONObject(enc *gojay.Encoder) { - -} - -// IsNil checks if instance is nil -func (p *Payload) IsNil() bool { - return p == nil -} - -// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject -func (p *Payload) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - - switch k { - - } - return nil -} - -// NKeys returns the number of keys to unmarshal -func (p *Payload) NKeys() int { return 0 } - -// MarshalJSONObject implements MarshalerJSONObject -func (m *Message) MarshalJSONObject(enc *gojay.Encoder) { - enc.IntKey("id", m.Id) - enc.StringKey("name", m.Name) - enc.Float64Key("price", m.Price) - var intsSlice = Ints(m.Ints) - enc.ArrayKey("ints", intsSlice) - var floatsSlice = Float32s(m.Floats) - enc.ArrayKey("floats", floatsSlice) - enc.ObjectKey("subMessageX", m.SubMessageX) - var messagesXSlice = SubMessagesPtr(m.MessagesX) - enc.ArrayKey("messagesX", messagesXSlice) - enc.ObjectKey("SubMessageY", &m.SubMessageY) - var messagesYSlice = SubMessages(m.MessagesY) - enc.ArrayKey("MessagesY", messagesYSlice) - enc.BoolKey("enabled", *m.IsTrue) - var payloadSlice = gojay.EmbeddedJSON(m.Payload) - enc.AddEmbeddedJSONKey("data", &payloadSlice) - if m.SQLNullString != nil { - enc.SQLNullStringKey("sqlNullString", m.SQLNullString) - } -} - -// IsNil checks if instance is nil -func (m *Message) IsNil() bool { - return m == nil -} - -// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject -func (m *Message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - - switch k { - case "id": - return dec.Int(&m.Id) - - case "name": - return dec.String(&m.Name) - - case "price": - return dec.Float64(&m.Price) - - case "ints": - var aSlice = Ints{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.Ints = []int(aSlice) - } - return err - - case "floats": - var aSlice = Float32s{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.Floats = []float32(aSlice) - } - return err - - case "subMessageX": - var value = &SubMessage{} - err := dec.Object(value) - if err == nil { - m.SubMessageX = value - } - - return err - - case "messagesX": - var aSlice = SubMessagesPtr{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.MessagesX = []*SubMessage(aSlice) - } - return err - - case "SubMessageY": - err := dec.Object(&m.SubMessageY) - - return err - - case "MessagesY": - var aSlice = SubMessages{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.MessagesY = []SubMessage(aSlice) - } - return err - - case "enabled": - var value bool - err := dec.Bool(&value) - if err == nil { - m.IsTrue = &value - } - return err - - case "data": - var value = gojay.EmbeddedJSON{} - err := dec.AddEmbeddedJSON(&value) - if err == nil && len(value) > 0 { - m.Payload = Payload(value) - } - return err - - case "sqlNullString": - var value = &sql.NullString{} - err := dec.SQLNullString(value) - if err == nil { - m.SQLNullString = value - } - return err - - } - return nil -} - -// NKeys returns the number of keys to unmarshal -func (m *Message) NKeys() int { return 12 } - -// MarshalJSONObject implements MarshalerJSONObject -func (m *SubMessage) MarshalJSONObject(enc *gojay.Encoder) { - enc.IntKey("id", m.Id) - enc.StringKey("description", m.Description) - enc.TimeKey("startDate", &m.StartTime, "2006-01-02 15:04:05") - if m.EndTime != nil { - enc.TimeKey("endDate", m.EndTime, "2006-01-02 15:04:05") - } -} - -// IsNil checks if instance is nil -func (m *SubMessage) IsNil() bool { - return m == nil -} - -// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject -func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - - switch k { - case "id": - return dec.Int(&m.Id) - - case "description": - return dec.String(&m.Description) - - case "startDate": - var format = "2006-01-02 15:04:05" - var value = time.Time{} - err := dec.Time(&value, format) - if err == nil { - m.StartTime = value - } - return err - - case "endDate": - var format = "2006-01-02 15:04:05" - var value = &time.Time{} - err := dec.Time(value, format) - if err == nil { - m.EndTime = value - } - return err - - } - return nil -} - -// NKeys returns the number of keys to unmarshal -func (m *SubMessage) NKeys() int { return 4 } diff --git a/gojay/codegen/test/annotated_struct/encoding_test.go b/gojay/codegen/test/annotated_struct/encoding_test.go @@ -1,126 +0,0 @@ -package annotated_struct - -import ( - "bytes" - "database/sql" - "log" - "testing" - - "github.com/francoispqt/gojay" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -var isTrue = true -var msg = &Message{ - Id: 1022, - Name: "name acc", - Price: 13.3, - Ints: []int{1, 2, 5}, - Floats: []float32{2.3, 4.6, 7.4}, - SubMessageX: &SubMessage{ - Id: 102, - Description: "abcd", - }, - MessagesX: []*SubMessage{ - &SubMessage{ - Id: 2102, - Description: "abce", - }, - }, - SubMessageY: SubMessage{ - Id: 3102, - Description: "abcf", - }, - MessagesY: []SubMessage{ - SubMessage{ - Id: 5102, - Description: "abcg", - }, - SubMessage{ - Id: 5106, - Description: "abcgg", - }, - }, - IsTrue: &isTrue, - Payload: []byte(`"123"`), - SQLNullString: &sql.NullString{ - String: "test", - Valid: true, - }, -} - -var jsonData = `{ - "id": 1022, - "name": "name acc", - "price": 13.3, - "ints": [ - 1, - 2, - 5 - ], - "floats": [ - 2.3, - 4.6, - 7.4 - ], - "subMessageX": { - "id": 102, - "description": "abcd", - "startDate": "0001-01-01 00:00:00" - }, - "messagesX": [ - { - "id": 2102, - "description": "abce", - "startDate": "0001-01-01 00:00:00" - } - ], - "SubMessageY": { - "id": 3102, - "description": "abcf", - "startDate": "0001-01-01 00:00:00" - }, - "MessagesY": [ - { - "id": 5102, - "description": "abcg", - "startDate": "0001-01-01 00:00:00" - }, - { - "id": 5106, - "description": "abcgg", - "startDate": "0001-01-01 00:00:00" - } - ], - "enabled": true, - "data": "123", - "sqlNullString": "test" -}` - -func TestMessage_Unmarshal(t *testing.T) { - - var err error - var data = []byte(jsonData) - message := &Message{} - err = gojay.UnmarshalJSONObject(data, message) - if !assert.Nil(t, err) { - log.Fatal(err) - } - require.Equal( - t, - msg, - message, - ) -} - -func TestMessage_Marshal(t *testing.T) { - var err error - var writer = new(bytes.Buffer) - encoder := gojay.NewEncoder(writer) - err = encoder.Encode(msg) - assert.Nil(t, err) - var JSON = writer.String() - require.JSONEq(t, jsonData, JSON) - -} diff --git a/gojay/codegen/test/annotated_struct/message.go b/gojay/codegen/test/annotated_struct/message.go @@ -1,21 +0,0 @@ -package annotated_struct - -import "database/sql" - -type Payload []byte - -type Message struct { - Id int `json:"id"` - Name string `json:"name"` - Price float64 `json:"price"` - Ints []int `json:"ints"` - Floats []float32 `json:"floats"` - SubMessageX *SubMessage `json:"subMessageX"` - MessagesX []*SubMessage `json:"messagesX"` - SubMessageY SubMessage - MessagesY []SubMessage - IsTrue *bool `json:"enabled"` - Payload Payload `json:"data"` - Ignore string `json:"-"` - SQLNullString *sql.NullString `json:"sqlNullString"` -} diff --git a/gojay/codegen/test/annotated_struct/sub_message.go b/gojay/codegen/test/annotated_struct/sub_message.go @@ -1,10 +0,0 @@ -package annotated_struct - -import "time" - -type SubMessage struct { - Id int `json:"id"` - Description string `json:"description"` - StartTime time.Time `json:"startDate" timeFormat:"yyyy-MM-dd HH:mm:ss"` - EndTime *time.Time `json:"endDate" timeLayout:"2006-01-02 15:04:05"` -} diff --git a/gojay/codegen/test/basic_struct/encoding.go b/gojay/codegen/test/basic_struct/encoding.go @@ -1,267 +0,0 @@ -// Code generated by Gojay. DO NOT EDIT. - -package basic_struct - -import ( - "database/sql" - "github.com/francoispqt/gojay" - "time" -) - -type SubMessagesPtr []*SubMessage - -func (s *SubMessagesPtr) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value = &SubMessage{} - if err := dec.Object(value); err != nil { - return err - } - *s = append(*s, value) - return nil -} - -func (s SubMessagesPtr) MarshalJSONArray(enc *gojay.Encoder) { - for i := range s { - enc.Object(s[i]) - } -} - -func (s SubMessagesPtr) IsNil() bool { - return len(s) == 0 -} - -type SubMessages []SubMessage - -func (s *SubMessages) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value = SubMessage{} - if err := dec.Object(&value); err != nil { - return err - } - *s = append(*s, value) - return nil -} - -func (s SubMessages) MarshalJSONArray(enc *gojay.Encoder) { - for i := range s { - enc.Object(&s[i]) - } -} - -func (s SubMessages) IsNil() bool { - return len(s) == 0 -} - -type Ints []int - -// UnmarshalJSONArray decodes JSON array elements into slice -func (a *Ints) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value int - if err := dec.Int(&value); err != nil { - return err - } - *a = append(*a, value) - return nil -} - -// MarshalJSONArray encodes arrays into JSON -func (a Ints) MarshalJSONArray(enc *gojay.Encoder) { - for _, item := range a { - enc.Int(item) - } -} - -// IsNil checks if array is nil -func (a Ints) IsNil() bool { - return len(a) == 0 -} - -type Float32s []float32 - -// UnmarshalJSONArray decodes JSON array elements into slice -func (a *Float32s) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value float32 - if err := dec.Float32(&value); err != nil { - return err - } - *a = append(*a, value) - return nil -} - -// MarshalJSONArray encodes arrays into JSON -func (a Float32s) MarshalJSONArray(enc *gojay.Encoder) { - for _, item := range a { - enc.Float32(item) - } -} - -// IsNil checks if array is nil -func (a Float32s) IsNil() bool { - return len(a) == 0 -} - -// MarshalJSONObject implements MarshalerJSONObject -func (m *SubMessage) MarshalJSONObject(enc *gojay.Encoder) { - enc.IntKey("Id", m.Id) - enc.StringKey("Description", m.Description) - enc.TimeKey("StartTime", &m.StartTime, time.RFC3339) - if m.EndTime != nil { - enc.TimeKey("EndTime", m.EndTime, time.RFC3339) - } -} - -// IsNil checks if instance is nil -func (m *SubMessage) IsNil() bool { - return m == nil -} - -// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject -func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - - switch k { - case "Id": - return dec.Int(&m.Id) - - case "Description": - return dec.String(&m.Description) - - case "StartTime": - var format = time.RFC3339 - var value = time.Time{} - err := dec.Time(&value, format) - if err == nil { - m.StartTime = value - } - return err - - case "EndTime": - var format = time.RFC3339 - var value = &time.Time{} - err := dec.Time(value, format) - if err == nil { - m.EndTime = value - } - return err - - } - return nil -} - -// NKeys returns the number of keys to unmarshal -func (m *SubMessage) NKeys() int { return 4 } - -// MarshalJSONObject implements MarshalerJSONObject -func (m *Message) MarshalJSONObject(enc *gojay.Encoder) { - enc.IntKey("Id", m.Id) - enc.StringKey("Name", m.Name) - enc.Float64Key("Price", m.Price) - var intsSlice = Ints(m.Ints) - enc.ArrayKey("Ints", intsSlice) - var floatsSlice = Float32s(m.Floats) - enc.ArrayKey("Floats", floatsSlice) - enc.ObjectKey("SubMessageX", m.SubMessageX) - var messagesXSlice = SubMessagesPtr(m.MessagesX) - enc.ArrayKey("MessagesX", messagesXSlice) - enc.ObjectKey("SubMessageY", &m.SubMessageY) - var messagesYSlice = SubMessages(m.MessagesY) - enc.ArrayKey("MessagesY", messagesYSlice) - enc.BoolKey("IsTrue", *m.IsTrue) - var payloadSlice = gojay.EmbeddedJSON(m.Payload) - enc.AddEmbeddedJSONKey("Payload", &payloadSlice) - if m.SQLNullString != nil { - enc.SQLNullStringKey("SQLNullString", m.SQLNullString) - } -} - -// IsNil checks if instance is nil -func (m *Message) IsNil() bool { - return m == nil -} - -// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject -func (m *Message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - - switch k { - case "Id": - return dec.Int(&m.Id) - - case "Name": - return dec.String(&m.Name) - - case "Price": - return dec.Float64(&m.Price) - - case "Ints": - var aSlice = Ints{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.Ints = []int(aSlice) - } - return err - - case "Floats": - var aSlice = Float32s{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.Floats = []float32(aSlice) - } - return err - - case "SubMessageX": - var value = &SubMessage{} - err := dec.Object(value) - if err == nil { - m.SubMessageX = value - } - - return err - - case "MessagesX": - var aSlice = SubMessagesPtr{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.MessagesX = []*SubMessage(aSlice) - } - return err - - case "SubMessageY": - err := dec.Object(&m.SubMessageY) - - return err - - case "MessagesY": - var aSlice = SubMessages{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.MessagesY = []SubMessage(aSlice) - } - return err - - case "IsTrue": - var value bool - err := dec.Bool(&value) - if err == nil { - m.IsTrue = &value - } - return err - - case "Payload": - var value = gojay.EmbeddedJSON{} - err := dec.AddEmbeddedJSON(&value) - if err == nil && len(value) > 0 { - m.Payload = []byte(value) - } - return err - - case "SQLNullString": - var value = &sql.NullString{} - err := dec.SQLNullString(value) - if err == nil { - m.SQLNullString = value - } - return err - - } - return nil -} - -// NKeys returns the number of keys to unmarshal -func (m *Message) NKeys() int { return 12 } diff --git a/gojay/codegen/test/basic_struct/encoding_test.go b/gojay/codegen/test/basic_struct/encoding_test.go @@ -1,118 +0,0 @@ -package basic_struct - -import ( - "bytes" - "database/sql" - "testing" - - "github.com/francoispqt/gojay" - "github.com/stretchr/testify/require" -) - -var isTrue = true -var msg = &Message{ - Id: 1022, - Name: "name acc", - Price: 13.3, - Ints: []int{1, 2, 5}, - Floats: []float32{2.3, 4.6, 7.4}, - SubMessageX: &SubMessage{ - Id: 102, - Description: "abcd", - }, - MessagesX: []*SubMessage{ - &SubMessage{ - Id: 2102, - Description: "abce", - }, - }, - SubMessageY: SubMessage{ - Id: 3102, - Description: "abcf", - }, - MessagesY: []SubMessage{ - SubMessage{ - Id: 5102, - Description: "abcg", - }, - SubMessage{ - Id: 5106, - Description: "abcgg", - }, - }, - IsTrue: &isTrue, - Payload: []byte(`"123"`), - SQLNullString: &sql.NullString{ - String: "test", - Valid: true, - }, -} - -var jsonData = `{ - "Id": 1022, - "Name": "name acc", - "Price": 13.3, - "Ints": [ - 1, - 2, - 5 - ], - "Floats": [ - 2.3, - 4.6, - 7.4 - ], - "SubMessageX": { - "Id": 102, - "Description": "abcd", - "StartTime": "0001-01-01T00:00:00Z" - }, - "MessagesX": [ - { - "Id": 2102, - "Description": "abce", - "StartTime": "0001-01-01T00:00:00Z" - } - ], - "SubMessageY": { - "Id": 3102, - "Description": "abcf", - "StartTime": "0001-01-01T00:00:00Z" - }, - "MessagesY": [ - { - "Id": 5102, - "Description": "abcg", - "StartTime": "0001-01-01T00:00:00Z" - }, - { - "Id": 5106, - "Description": "abcgg", - "StartTime": "0001-01-01T00:00:00Z" - } - ], - "IsTrue": true, - "Payload": "123", - "SQLNullString": "test" -}` - -func TestMessage_Unmarshal(t *testing.T) { - var err error - var data = []byte(jsonData) - message := &Message{} - err = gojay.UnmarshalJSONObject(data, message) - require.Nil(t, err) - require.Equal(t, msg, message) -} - -func TestMessage_Marshal(t *testing.T) { - var writer = new(bytes.Buffer) - - encoder := gojay.NewEncoder(writer) - var err = encoder.Encode(msg) - - require.Nil(t, err) - var JSON = writer.String() - - require.JSONEq(t, jsonData, JSON) -} diff --git a/gojay/codegen/test/basic_struct/message.go b/gojay/codegen/test/basic_struct/message.go @@ -1,18 +0,0 @@ -package basic_struct - -import "database/sql" - -type Message struct { - Id int - Name string - Price float64 - Ints []int - Floats []float32 - SubMessageX *SubMessage - MessagesX []*SubMessage - SubMessageY SubMessage - MessagesY []SubMessage - IsTrue *bool - Payload []byte - SQLNullString *sql.NullString -} diff --git a/gojay/codegen/test/basic_struct/sub_message.go b/gojay/codegen/test/basic_struct/sub_message.go @@ -1,10 +0,0 @@ -package basic_struct - -import "time" - -type SubMessage struct { - Id int - Description string - StartTime time.Time - EndTime *time.Time -} diff --git a/gojay/codegen/test/embedded_struct/encoding.go b/gojay/codegen/test/embedded_struct/encoding.go @@ -1,309 +0,0 @@ -// Code generated by Gojay. DO NOT EDIT. - -package embedded_struct - -import ( - "github.com/francoispqt/gojay" - "time" -) - -type Ints []int - -// UnmarshalJSONArray decodes JSON array elements into slice -func (a *Ints) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value int - if err := dec.Int(&value); err != nil { - return err - } - *a = append(*a, value) - return nil -} - -// MarshalJSONArray encodes arrays into JSON -func (a Ints) MarshalJSONArray(enc *gojay.Encoder) { - for _, item := range a { - enc.Int(item) - } -} - -// IsNil checks if array is nil -func (a Ints) IsNil() bool { - return len(a) == 0 -} - -type Float64s []float64 - -// UnmarshalJSONArray decodes JSON array elements into slice -func (a *Float64s) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value float64 - if err := dec.Float64(&value); err != nil { - return err - } - *a = append(*a, value) - return nil -} - -// MarshalJSONArray encodes arrays into JSON -func (a Float64s) MarshalJSONArray(enc *gojay.Encoder) { - for _, item := range a { - enc.Float64(item) - } -} - -// IsNil checks if array is nil -func (a Float64s) IsNil() bool { - return len(a) == 0 -} - -type SubMessagesPtr []*SubMessage - -func (s *SubMessagesPtr) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value = &SubMessage{} - if err := dec.Object(value); err != nil { - return err - } - *s = append(*s, value) - return nil -} - -func (s SubMessagesPtr) MarshalJSONArray(enc *gojay.Encoder) { - for i := range s { - enc.Object(s[i]) - } -} - -func (s SubMessagesPtr) IsNil() bool { - return len(s) == 0 -} - -type SubMessages []SubMessage - -func (s *SubMessages) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value = SubMessage{} - if err := dec.Object(&value); err != nil { - return err - } - *s = append(*s, value) - return nil -} - -func (s SubMessages) MarshalJSONArray(enc *gojay.Encoder) { - for i := range s { - enc.Object(&s[i]) - } -} - -func (s SubMessages) IsNil() bool { - return len(s) == 0 -} - -// MarshalJSONObject implements MarshalerJSONObject -func (m *SubMessage) MarshalJSONObject(enc *gojay.Encoder) { - enc.StringKey("Description", m.Description) - enc.TimeKey("StartTime", &m.StartTime, time.RFC3339) - if m.EndTime != nil { - enc.TimeKey("EndTime", m.EndTime, time.RFC3339) - } -} - -// IsNil checks if instance is nil -func (m *SubMessage) IsNil() bool { - return m == nil -} - -// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject -func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - - switch k { - case "Description": - return dec.String(&m.Description) - - case "StartTime": - var format = time.RFC3339 - var value = time.Time{} - err := dec.Time(&value, format) - if err == nil { - m.StartTime = value - } - return err - - case "EndTime": - var format = time.RFC3339 - var value = &time.Time{} - err := dec.Time(value, format) - if err == nil { - m.EndTime = value - } - return err - - } - return nil -} - -// NKeys returns the number of keys to unmarshal -func (m *SubMessage) NKeys() int { return 3 } - -// MarshalJSONObject implements MarshalerJSONObject -func (m *Message) MarshalJSONObject(enc *gojay.Encoder) { - if m.BaseId != nil { - enc.IntKey("Id", m.Id) - enc.StringKey("Name", m.Name) - } - enc.StringKey("Description", m.Description) - enc.TimeKey("StartTime", &m.StartTime, time.RFC3339) - if m.EndTime != nil { - enc.TimeKey("EndTime", m.EndTime, time.RFC3339) - } - enc.Float64Key("Price", m.Price) - var intsSlice = Ints(m.Ints) - enc.ArrayKey("Ints", intsSlice) - var floatsSlice = Float64s(m.Floats) - enc.ArrayKey("Floats", floatsSlice) - enc.ObjectKey("SubMessageX", m.SubMessageX) - var messagesXSlice = SubMessagesPtr(m.MessagesX) - enc.ArrayKey("MessagesX", messagesXSlice) - enc.ObjectKey("SubMessageY", &m.SubMessageY) - var messagesYSlice = SubMessages(m.MessagesY) - enc.ArrayKey("MessagesY", messagesYSlice) - enc.BoolKey("IsTrue", *m.IsTrue) - var payloadSlice = gojay.EmbeddedJSON(m.Payload) - enc.AddEmbeddedJSONKey("Payload", &payloadSlice) -} - -// IsNil checks if instance is nil -func (m *Message) IsNil() bool { - return m == nil -} - -// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject -func (m *Message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - if m.BaseId == nil { - m.BaseId = &BaseId{} - } - switch k { - case "Id": - return dec.Int(&m.Id) - - case "Name": - return dec.String(&m.Name) - - case "Description": - return dec.String(&m.Description) - - case "StartTime": - var format = time.RFC3339 - var value = time.Time{} - err := dec.Time(&value, format) - if err == nil { - m.StartTime = value - } - return err - - case "EndTime": - var format = time.RFC3339 - var value = &time.Time{} - err := dec.Time(value, format) - if err == nil { - m.EndTime = value - } - return err - - case "Price": - return dec.Float64(&m.Price) - - case "Ints": - var aSlice = Ints{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.Ints = []int(aSlice) - } - return err - - case "Floats": - var aSlice = Float64s{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.Floats = []float64(aSlice) - } - return err - - case "SubMessageX": - var value = &SubMessage{} - err := dec.Object(value) - if err == nil { - m.SubMessageX = value - } - - return err - - case "MessagesX": - var aSlice = SubMessagesPtr{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.MessagesX = []*SubMessage(aSlice) - } - return err - - case "SubMessageY": - err := dec.Object(&m.SubMessageY) - - return err - - case "MessagesY": - var aSlice = SubMessages{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.MessagesY = []SubMessage(aSlice) - } - return err - - case "IsTrue": - var value bool - err := dec.Bool(&value) - if err == nil { - m.IsTrue = &value - } - return err - - case "Payload": - var value = gojay.EmbeddedJSON{} - err := dec.AddEmbeddedJSON(&value) - if err == nil && len(value) > 0 { - m.Payload = []byte(value) - } - return err - - } - return nil -} - -// NKeys returns the number of keys to unmarshal -func (m *Message) NKeys() int { return 14 } - -// MarshalJSONObject implements MarshalerJSONObject -func (i *BaseId) MarshalJSONObject(enc *gojay.Encoder) { - enc.IntKey("Id", i.Id) - enc.StringKey("Name", i.Name) -} - -// IsNil checks if instance is nil -func (i *BaseId) IsNil() bool { - return i == nil -} - -// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject -func (i *BaseId) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - - switch k { - case "Id": - return dec.Int(&i.Id) - - case "Name": - return dec.String(&i.Name) - - } - return nil -} - -// NKeys returns the number of keys to unmarshal -func (i *BaseId) NKeys() int { return 2 } diff --git a/gojay/codegen/test/embedded_struct/encoding_test.go b/gojay/codegen/test/embedded_struct/encoding_test.go @@ -1,106 +0,0 @@ -package embedded_struct - -import ( - "bytes" - "github.com/francoispqt/gojay" - "github.com/stretchr/testify/assert" - "github.com/viant/assertly" - "testing" -) - -func TestMessage_Unmarshal(t *testing.T) { - - input := `{ - "Id": 1022, - "Name": "name acc", - "Description": "abcd", - "Price": 13.3, - "Ints": [ - 1, - 2, - 5 - ], - "Floats": [ - 2.3, - 4.6, - 7.4 - ], - "MessagesX": [ - { - "Description": "abce" - } - ], - "SubMessageY": { - "Description": "abcf" - }, - "MessagesY": [ - { - "Description": "abcg" - }, - { - "Description": "abcgg" - } - ], - "IsTrue": true, - "Payload": "" -}` - - var err error - var data = []byte(input) - message := &Message{} - err = gojay.UnmarshalJSONObject(data, message) - assert.Nil(t, err) - assertly.AssertValues(t, input, message) -} - -func TestMessage_Marshal(t *testing.T) { - - input := `{ - "Id": 1022, - "Name": "name acc", - "Description": "abcd", - "Price": 13.3, - "Ints": [ - 1, - 2, - 5 - ], - "Floats": [ - 2.3, - 4.6, - 7.4 - ], - "MessagesX": [ - { - "Description": "abce" - } - ], - "SubMessageY": { - "Description": "abcf" - }, - "MessagesY": [ - { - "Description": "abcg" - }, - { - "Description": "abcgg" - } - ], - "IsTrue": true, - "Payload": "" -}` - - var err error - var data = []byte(input) - message := &Message{} - err = gojay.UnmarshalJSONObject(data, message) - assert.Nil(t, err) - assertly.AssertValues(t, input, message) - var writer = new(bytes.Buffer) - - encoder := gojay.NewEncoder(writer) - err = encoder.Encode(message) - assert.Nil(t, err) - var JSON = writer.String() - assertly.AssertValues(t, input, JSON) -} diff --git a/gojay/codegen/test/embedded_struct/message.go b/gojay/codegen/test/embedded_struct/message.go @@ -1,20 +0,0 @@ -package embedded_struct - -type BaseId struct { - Id int - Name string -} - -type Message struct { - *BaseId - SubMessage - Price float64 - Ints []int - Floats []float64 - SubMessageX *SubMessage - MessagesX []*SubMessage - SubMessageY SubMessage - MessagesY []SubMessage - IsTrue *bool - Payload []byte -} diff --git a/gojay/codegen/test/embedded_struct/sub_message.go b/gojay/codegen/test/embedded_struct/sub_message.go @@ -1,9 +0,0 @@ -package embedded_struct - -import "time" - -type SubMessage struct { - Description string - StartTime time.Time - EndTime *time.Time -} diff --git a/gojay/codegen/test/pooled_struct/encoding.go b/gojay/codegen/test/pooled_struct/encoding.go @@ -1,302 +0,0 @@ -// Code generated by Gojay. DO NOT EDIT. - -package pooled_struct - -import ( - "github.com/francoispqt/gojay" - "sync" - "time" -) - -func init() { - MessagePool = &sync.Pool{ - New: func() interface{} { - return &Message{} - }, - } - SubMessagePool = &sync.Pool{ - New: func() interface{} { - return &SubMessage{} - }, - } -} - -var MessagePool *sync.Pool -var SubMessagePool *sync.Pool - -type Ints []int - -// UnmarshalJSONArray decodes JSON array elements into slice -func (a *Ints) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value int - if err := dec.Int(&value); err != nil { - return err - } - *a = append(*a, value) - return nil -} - -// MarshalJSONArray encodes arrays into JSON -func (a Ints) MarshalJSONArray(enc *gojay.Encoder) { - for _, item := range a { - enc.Int(item) - } -} - -// IsNil checks if array is nil -func (a Ints) IsNil() bool { - return len(a) == 0 -} - -type Float64s []float64 - -// UnmarshalJSONArray decodes JSON array elements into slice -func (a *Float64s) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value float64 - if err := dec.Float64(&value); err != nil { - return err - } - *a = append(*a, value) - return nil -} - -// MarshalJSONArray encodes arrays into JSON -func (a Float64s) MarshalJSONArray(enc *gojay.Encoder) { - for _, item := range a { - enc.Float64(item) - } -} - -// IsNil checks if array is nil -func (a Float64s) IsNil() bool { - return len(a) == 0 -} - -type SubMessagesPtr []*SubMessage - -func (s *SubMessagesPtr) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value = &SubMessage{} - if err := dec.Object(value); err != nil { - return err - } - *s = append(*s, value) - return nil -} - -func (s SubMessagesPtr) MarshalJSONArray(enc *gojay.Encoder) { - for i := range s { - enc.Object(s[i]) - } -} - -func (s SubMessagesPtr) IsNil() bool { - return len(s) == 0 -} - -type SubMessages []SubMessage - -func (s *SubMessages) UnmarshalJSONArray(dec *gojay.Decoder) error { - var value = SubMessage{} - if err := dec.Object(&value); err != nil { - return err - } - *s = append(*s, value) - return nil -} - -func (s SubMessages) MarshalJSONArray(enc *gojay.Encoder) { - for i := range s { - enc.Object(&s[i]) - } -} - -func (s SubMessages) IsNil() bool { - return len(s) == 0 -} - -// MarshalJSONObject implements MarshalerJSONObject -func (m *SubMessage) MarshalJSONObject(enc *gojay.Encoder) { - enc.IntKey("Id", m.Id) - enc.StringKey("Description", m.Description) - enc.TimeKey("StartTime", &m.StartTime, time.RFC3339) - if m.EndTime != nil { - enc.TimeKey("EndTime", m.EndTime, time.RFC3339) - } -} - -// IsNil checks if instance is nil -func (m *SubMessage) IsNil() bool { - return m == nil -} - -// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject -func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - - switch k { - case "Id": - return dec.Int(&m.Id) - - case "Description": - return dec.String(&m.Description) - - case "StartTime": - var format = time.RFC3339 - var value = time.Time{} - err := dec.Time(&value, format) - if err == nil { - m.StartTime = value - } - return err - - case "EndTime": - var format = time.RFC3339 - var value = &time.Time{} - err := dec.Time(value, format) - if err == nil { - m.EndTime = value - } - return err - - } - return nil -} - -// NKeys returns the number of keys to unmarshal -func (m *SubMessage) NKeys() int { return 4 } - -// Reset reset fields -func (m *SubMessage) Reset() { - m.Id = 0 - m.Description = "" - m.EndTime = nil -} - -// MarshalJSONObject implements MarshalerJSONObject -func (m *Message) MarshalJSONObject(enc *gojay.Encoder) { - enc.IntKey("Id", m.Id) - enc.StringKey("Name", m.Name) - enc.Float64Key("Price", m.Price) - var intsSlice = Ints(m.Ints) - enc.ArrayKey("Ints", intsSlice) - var floatsSlice = Float64s(m.Floats) - enc.ArrayKey("Floats", floatsSlice) - enc.ObjectKey("SubMessageX", m.SubMessageX) - var messagesXSlice = SubMessagesPtr(m.MessagesX) - enc.ArrayKey("MessagesX", messagesXSlice) - enc.ObjectKey("SubMessageY", &m.SubMessageY) - var messagesYSlice = SubMessages(m.MessagesY) - enc.ArrayKey("MessagesY", messagesYSlice) - enc.BoolKey("IsTrue", *m.IsTrue) - var payloadSlice = gojay.EmbeddedJSON(m.Payload) - enc.AddEmbeddedJSONKey("Payload", &payloadSlice) -} - -// IsNil checks if instance is nil -func (m *Message) IsNil() bool { - return m == nil -} - -// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject -func (m *Message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - - switch k { - case "Id": - return dec.Int(&m.Id) - - case "Name": - return dec.String(&m.Name) - - case "Price": - return dec.Float64(&m.Price) - - case "Ints": - var aSlice = Ints{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.Ints = []int(aSlice) - } - return err - - case "Floats": - var aSlice = Float64s{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.Floats = []float64(aSlice) - } - return err - - case "SubMessageX": - var value = SubMessagePool.Get().(*SubMessage) - err := dec.Object(value) - if err == nil { - m.SubMessageX = value - } - - return err - - case "MessagesX": - var aSlice = SubMessagesPtr{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.MessagesX = []*SubMessage(aSlice) - } - return err - - case "SubMessageY": - err := dec.Object(&m.SubMessageY) - - return err - - case "MessagesY": - var aSlice = SubMessages{} - err := dec.Array(&aSlice) - if err == nil && len(aSlice) > 0 { - m.MessagesY = []SubMessage(aSlice) - } - return err - - case "IsTrue": - var value bool - err := dec.Bool(&value) - if err == nil { - m.IsTrue = &value - } - return err - - case "Payload": - var value = gojay.EmbeddedJSON{} - err := dec.AddEmbeddedJSON(&value) - if err == nil && len(value) > 0 { - m.Payload = []byte(value) - } - return err - - } - return nil -} - -// NKeys returns the number of keys to unmarshal -func (m *Message) NKeys() int { return 11 } - -// Reset reset fields -func (m *Message) Reset() { - m.Id = 0 - m.Name = "" - m.Price = 0.0 - m.Ints = nil - m.Floats = nil - SubMessagePool.Put(m.SubMessageX) - m.SubMessageX = nil - for i := range m.MessagesX { - m.MessagesX[i].Reset() - SubMessagePool.Put(m.MessagesX[i]) - } - m.MessagesX = nil - for i := range m.MessagesY { - m.MessagesY[i].Reset() - SubMessagePool.Put(&m.MessagesY[i]) - } - m.MessagesY = nil - m.IsTrue = nil - m.Payload = nil -} diff --git a/gojay/codegen/test/pooled_struct/encoding_test.go b/gojay/codegen/test/pooled_struct/encoding_test.go @@ -1,123 +0,0 @@ -package pooled_struct - -import ( - "bytes" - "github.com/francoispqt/gojay" - "github.com/stretchr/testify/assert" - "github.com/viant/assertly" - "testing" -) - -func TestMessage_Unmarshal(t *testing.T) { - - input := `{ - "Id": 1022, - "Name": "name acc", - "Price": 13.3, - "Ints": [ - 1, - 2, - 5 - ], - "Floats": [ - 2.3, - 4.6, - 7.4 - ], - "SubMessageX": { - "Id": 102, - "Description": "abcd" - }, - "MessagesX": [ - { - "Id": 2102, - "Description": "abce" - } - ], - "SubMessageY": { - "Id": 3102, - "Description": "abcf" - }, - "MessagesY": [ - { - "Id": 5102, - "Description": "abcg" - }, - { - "Id": 5106, - "Description": "abcgg" - } - ], - "IsTrue": true, - "Payload": "" -}` - - var data = []byte(input) - message := MessagePool.Get().(*Message) - err := gojay.UnmarshalJSONObject(data, message) - assert.Nil(t, err) - message.Reset() - MessagePool.Put(message) - -} - -func TestMessage_Marshal(t *testing.T) { - - input := `{ - "Id": 1022, - "Name": "name acc", - "Price": 13.3, - "Ints": [ - 1, - 2, - 5 - ], - "Floats": [ - 2.3, - 4.6, - 7.4 - ], - "SubMessageX": { - "Id": 102, - "Description": "abcd" - }, - "MessagesX": [ - { - "Id": 2102, - "Description": "abce" - } - ], - "SubMessageY": { - "Id": 3102, - "Description": "abcf" - }, - "MessagesY": [ - { - "Id": 5102, - "Description": "abcg" - }, - { - "Id": 5106, - "Description": "abcgg" - } - ], - "IsTrue": true, - "Payload": "" -}` - - var data = []byte(input) - message := MessagePool.Get().(*Message) - err := gojay.UnmarshalJSONObject(data, message) - assert.Nil(t, err) - defer func() { - message.Reset() - MessagePool.Put(message) - - }() - var writer = new(bytes.Buffer) - encoder := gojay.NewEncoder(writer) - err = encoder.Encode(message) - assert.Nil(t, err) - var JSON = writer.String() - assertly.AssertValues(t, input, JSON) -} diff --git a/gojay/codegen/test/pooled_struct/message.go b/gojay/codegen/test/pooled_struct/message.go @@ -1,15 +0,0 @@ -package pooled_struct - -type Message struct { - Id int - Name string - Price float64 - Ints []int - Floats []float64 - SubMessageX *SubMessage - MessagesX []*SubMessage - SubMessageY SubMessage - MessagesY []SubMessage - IsTrue *bool - Payload []byte -} diff --git a/gojay/codegen/test/pooled_struct/sub_message.go b/gojay/codegen/test/pooled_struct/sub_message.go @@ -1,10 +0,0 @@ -package pooled_struct - -import "time" - -type SubMessage struct { - Id int - Description string - StartTime time.Time - EndTime *time.Time -} diff --git a/gojay/gojay.go b/gojay/gojay.go @@ -1,23 +0,0 @@ -package main - -import ( - "flag" - "github.com/francoispqt/gojay/gojay/codegen" - "log" -) - -var pkg = flag.String("pkg", "", "the package name of the generated file") -var dst = flag.String("o", "", "destination file to output generated code") -var src = flag.String("s", "", "source dir or file (absolute or relative path)") -var types = flag.String("t", "", "types to generate") -var annotation = flag.String("a", "json", "annotation tag (default json)") -var poolObjects = flag.String("p", "", "generate code to reuse objects using sync.Pool") - -func main() { - flag.Parse() - options := codegen.NewOptionsWithFlagSet(flag.CommandLine) - gen := codegen.NewGenerator(options) - if err := gen.Generate(); err != nil { - log.Fatal(err) - } -} diff --git a/gojay_example_test.go b/gojay_example_test.go @@ -6,7 +6,7 @@ import ( "os" "strings" - "github.com/francoispqt/gojay" + "go.lair.cx/gojay" ) type User struct {