{"id":17953657,"url":"https://github.com/akutz/gdj","last_synced_at":"2026-04-18T11:03:43.691Z","repository":{"id":65253164,"uuid":"578693848","full_name":"akutz/gdj","owner":"akutz","description":"Golang's \"encoding/json\" package with support for discriminators","archived":false,"fork":false,"pushed_at":"2023-09-24T18:58:55.000Z","size":254,"stargazers_count":1,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-31T20:04:33.458Z","etag":null,"topics":["discriminator","encoding","go","golang","json"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akutz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-15T16:55:34.000Z","updated_at":"2023-01-11T19:20:07.000Z","dependencies_parsed_at":"2024-10-29T10:39:58.586Z","dependency_job_id":null,"html_url":"https://github.com/akutz/gdj","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/akutz/gdj","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akutz%2Fgdj","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akutz%2Fgdj/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akutz%2Fgdj/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akutz%2Fgdj/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akutz","download_url":"https://codeload.github.com/akutz/gdj/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akutz%2Fgdj/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268240441,"owners_count":24218357,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["discriminator","encoding","go","golang","json"],"created_at":"2024-10-29T10:06:30.669Z","updated_at":"2026-04-18T11:03:43.662Z","avatar_url":"https://github.com/akutz.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go's Discriminating JSON (gdj)\n\nThis repository contains a fork of Golang's [`encoding/json`](https://pkg.go.dev/encoding/json) package, enhanced with support for encoding type information into objects via a [type discriminator](https://www.rfc-editor.org/rfc/rfc8927#name-discriminator).\n\n## Overview\n\nThis project enhances the Go package `encoding/json` with support for an optional, [type discriminator](https://www.rfc-editor.org/rfc/rfc8927#name-discriminator) when encoding/decoding values to/from JSON. For more information please see the associated, [JSON Discriminator Proposal](./proposal.md) that will be submitted to Go.\n\n## Goals\n\nThis project is intended to help drive the following goals:\n\n* Introduce support for a JSON discriminator in Go's `encoding/json` package\n* Make it easy for people to use JSON discriminators _today_ with minimal changes to their existing types/code\n* Support all versions of Go newer than or equal to 1.17.13, 1.18.9, 1.19.4, 1.20rc1\n\n## Getting started\n\nUsing this project is quite simple, just:\n\n1. import `github.com/akutz/gdj`\n1. create a new `json.Encoder` or `json.Decoder`\n1. set the discriminator on the new encoder/decoder\n\nThe following example illustrates a encoding and decoding JSON with a discriminator:\n\n```go\nimport \"github.com/akutz/gdj\" // imports as the \"json\" package\n\n// ...\n\ntype Person struct {\n\tName       string        `json:\"name\"`\n\tAttributes []interface{} `json:\"attributes,omitempty\"`\n}\n\ntype Spouse struct {\n\tPerson\n}\n\nenc := json.NewEncoder(os.Stdout)\nenc.SetDiscriminator(\"type\", \"value\", 0)\n\nenc.Encode(Person{\"Andrew\", []interface{}{\"Austin\", uint8(42)}})\nenc.Encode(Person{\"Mandy\", []interface{}{Spouse{Person{\"Andrew\", nil}}}})\n```\n\nThe above program will emit the following output:\n\n```\n{\"name\":\"Andrew\",\"attributes\":[{\"type\":\"string\",\"value\":\"Austin\"},{\"type\":\"uint8\",\"value\":42}]}\n{\"name\":\"Mandy\",\"attributes\":[{\"type\":\"Spouse\",\"name\":\"Andrew\"}]}\n```\n\nThe type information is encoded alongside the values for the elements in the field `Person.Attributes`. It is also possible to decode the information back to a `Person` while maintaining the same type information:\n\n```go\nvar jsonBlob = `{\n\t\"name\":\"Andrew\",\n\t\"attributes\":[\n\t\t{\"type\":\"string\", \"value\": \"Austin\"},\n\t\t{\"type\":\"uint8\", \"value\":42}\n\t]\n}\n{\n\t\"name\":\"Mandy\",\n\t\"attributes\":[\n\t\t{\"type\":\"Spouse\", \"name\": \"Andrew\"}\n\t]\n}`\n\ndec := json.NewDecoder(strings.NewReader(jsonBlob))\ndec.SetDiscriminator(\"type\", \"value\", func(s string) (reflect.Type, bool) {\n\tswitch s {\n\tcase \"Person\":\n\t\treturn reflect.TypeOf(Person{}), true\n\tcase \"Spouse\":\n\t\treturn reflect.TypeOf(Spouse{}), true\n\t}\n\treturn nil, false\n})\n\nvar p Person\ndec.Decode(\u0026p)\nfmt.Printf(\"%[1]T(%[1]d)\\n\", p.Attributes[1])\n\ndec.Decode(\u0026p)\nfmt.Printf(\"%[1]T(%[1]s)\\n\", p.Attributes[0].(Spouse).Name)\n```\n\nThe above program emits the following:\n\n```\nuint8(42)\nstring(Andrew)\n```\n\nThe output indicates the original type and value information was respected when the data was decoded. For more examples, please see:\n\n* [`discriminator_test.go`](./discriminator_test.go)\n* [`example_discriminator_test.go`](./example_discriminator_test.go)\n* [`govmomi_test.go`](./canaries/govmomi_test.go)\n\n\n## Type support\n\nThe discriminator supports encoding and decoding the following, built-in types:\n\n* `uint`\n* `uint8`\n* `uint16`\n* `uint32`\n* `uint64`\n* `uintptr`\n* `int`\n* `int8`\n* `int16`\n* `int32`\n* `int64`\n* `float32`\n* `float64`\n* `bool`\n* `string`\n\nEncoding custom types is supported as well, with decoding custom types dependent on the type lookup function provided to the decoder's `SetDiscriminator` function.\n\n\n## Testing\n\nThe discriminator functionality is thoroughly tested with:\n\n* the tests from the `encoding/json` package\n* ~300 encoding/decoding tests in [`discriminator_test.go`](./discriminator_test.go)\n* canary testing of complex type models in the [`canaries`] directory, ex. the GoVmomi `VirtualMachineConfigInfo` structure ([`govmomi_test.go`](./canaries/govmomi_test.go))\n\nAll of the above tests are executed:\n\n* on every pull request\n* push to the `main` branch\n* via the GitHub action, [`test` workflow](./.github/workflows/test.yml)\n* for all supported versions of Go, ex. 1.17.13, 1.18.9, 1.19.4, 1.20rc1\n\nIt is also possible to run the tests locally with `make test`. This depends on either:\n\n* an environment variable, `GO_\u003cVERSION\u003e_BIN`, for each version of Go tested that points to the Go installation's `go` binary, ex. `GO_1.17.3_BIN=\"${HOME}/.go/1.17.3/bin/go\"`\n* or Docker, which is used to run the tests with the official Golang container images\n\nThe command `make test` will attempt to use a local Go installation for a given version of Golang, and if one cannot be found, default to using Docker. It is also possible to force the use of Docker with `DOCKER=1 make test`.\n\n## License\n\nThis is a fork of Go's `encoding/json` package and so uses the same license as Golang.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakutz%2Fgdj","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakutz%2Fgdj","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakutz%2Fgdj/lists"}