A golang json library inspired by jsoniter

Go Report Card PkgGoDev Github Workflow Build Status codecov pre-commit

jzon

A high performance json library for Golang

Why another jsoniter?

The code I write here is very similar to github.com/json-iterator/go, so you may ask why reinvent the wheel.

For sure that I benefit a lot from the jsoniter library, but i found some inconvenience for me to use it in some condition, for example:

  • the iterator methods ReadString accepts null, there is no method which accepts exactly string. I have to do some extra check before calling.
  • some behavior is not compatible with the standard library.
  • I want a chained streamer

On the other hand, I also want to learn how the jsoniter works, so there is this repo.

What's different from jsoniter?

Here are some of the differences:

  • the iterator methods accept the exact type, for example ReadString accepts only string, not null
  • the behavior is almost the same as the standard library (when an error returns, the behavior may differ from the standard library)
  • the error of the iterator is returned instead of being saved inside iterator
  • the decoder/encoder interface has additional options, like struct tag options

Some features of jsoniter are not implemented, and may be not implemented in the future neither. I choose only the ones I need to implement.

Compatibility with standard library

I tried implemented a version which is completely compatible with the standard library:

https://github.com/zerosnake0/jzon/tree/reflect

The benchmark shows that it's much faster than the standard library. However it is still much slower than the current version, which cannot be exactly the same as standard library (at least in my POV).

The major incompatibility is about the two following interfaces:

  • json.Marshaler
  • encoding.TextMarshaler

The method on pointer receiver may be called with an unaddressable value, for example:

type field struct {}

func (*field) MarshalJSON() ([]byte, error)

type st struct {
    F field
}

json.Marshal(st{}) // will not call field.MarshalJSON
jzon.Marshal(st{}) // will call field.MarshalJSON

So the user should be care when marshaling a value when method on pointer receiver is involved

You can check the tests for more detailed info about the difference

How to use

Standard library like

import "github.com/zerosnake0/jzon"

// Unmarshal
err := jzon.Unmarshal(b, &data)

// Marshal
b, err := jzon.Marshal(&data)

// Decoder
dec := jzon.NewDecoder(reader)
defer dec.Release()
err := dec.Decode(&data)

// Encoder
enc := jzon.NewEncoder(writer)
defer enc.Release()
err := enc.Encode(&data)

Iterator

iter := jzon.NewIterator()
defer iter.Release()
iter.Reset(b)
jzon.ReadVal(&data)

Streamer

var w io.Writer

streamer := jzon.NewStreamer()
defer streamer.Release()
streamer.Reset(w)
streamer.Value(&data)
streamer.Flush()

Custom Decoder

see decoder_test.go

type testIntDecoder struct{}

func (*testIntDecoder) Decode(ptr unsafe.Pointer, it *Iterator, opts *DecOpts) error {
    ...
}

dec := NewDecoderConfig(&DecoderOption{
    ValDecoders: map[reflect.Type]ValDecoder{
        reflect.TypeOf(int(0)): (*testIntDecoder)(nil),
    },
    CaseSensitive: true,
})

// standard library like
err := dec.Unmarshal(b, &data)

// iterator
iter := dec.NewIterator()
defer iter.Release()

Custom Encoder

see encoder_test.go

type testIntEncoder struct{}

func (*testIntEncoder) IsEmpty(ptr unsafe.Pointer) bool {
    ...
}

func (*testIntEncoder) Encode(ptr unsafe.Pointer, s *Streamer, opts *EncOpts) {
    ...
}

enc := NewEncoderConfig(&EncoderOption{
    ValEncoders: map[reflect.Type]ValEncoder{
        reflect.TypeOf(int(0)): (*testIntEncoder)(nil),
    },
})

// standard library like
b, err := enc.Marshal(&data)

// streamer
streamer := enc.NewStreamer()
defer streamer.Release()
Owner
Interested in Golang, C++, Kubernetes, Docker, CNCF. PS: Currently not playing vanilla WoW so the addons will probably NOT be updated
null
Similar Resources

JSON Unmarshalling Library

JSAWN (JAY-sawn) This is a JSON library to add to the capabilities of the standard 'encoding/json' library. Unmarshalling The first enhancement is to

Feb 16, 2022

Abstract JSON for golang with JSONPath support

Abstract JSON Abstract JSON is a small golang package provides a parser for JSON with support of JSONPath, in case when you are not sure in its struct

Jan 5, 2023

JSON query in Golang

gojq JSON query in Golang. Install go get -u github.com/elgs/gojq This library serves three purposes: makes parsing JSON configuration file much easie

Dec 28, 2022

Automatically generate Go (golang) struct definitions from example JSON

gojson gojson generates go struct definitions from json or yaml documents. Example $ curl -s https://api.github.com/repos/chimeracoder/gojson | gojson

Jan 1, 2023

Arbitrary transformations of JSON in Golang

kazaam Description Kazaam was created with the goal of supporting easy and fast transformations of JSON data with Golang. This functionality provides

Dec 18, 2022

Parsing JSON is a hassle in golang

GoJSON Parsing JSON is a hassle in golang. This package will allow you to parse and search elements in a json without structs. Install gojson go get g

Nov 12, 2021

Fast JSON serializer for golang.

easyjson Package easyjson provides a fast and easy way to marshal/unmarshal Go structs to/from JSON without the use of reflection. In performance test

Jan 4, 2023

Fastest JSON interperter for golang

Welcome To JIN "Your wish is my command" Fast and Easy Way to Deal With JSON Jin is a comprehensive JSON manipulation tool bundle. All functions teste

Dec 14, 2022

Fast Color JSON Marshaller + Pretty Printer for Golang

Fast Color JSON Marshaller + Pretty Printer for Golang

ColorJSON: The Fast Color JSON Marshaller for Go What is this? This package is based heavily on hokaccha/go-prettyjson but has some noticible differen

Dec 19, 2022
Get JSON values quickly - JSON parser for Go
Get JSON values quickly - JSON parser for Go

get json values quickly GJSON is a Go package that provides a fast and simple way to get values from a json document. It has features such as one line

Dec 28, 2022
Fast JSON encoder/decoder compatible with encoding/json for Go
Fast JSON encoder/decoder compatible with encoding/json for Go

Fast JSON encoder/decoder compatible with encoding/json for Go

Jan 6, 2023
Package json implements encoding and decoding of JSON as defined in RFC 7159

Package json implements encoding and decoding of JSON as defined in RFC 7159. The mapping between JSON and Go values is described in the documentation for the Marshal and Unmarshal functions

Jun 26, 2022
Json-go - CLI to convert JSON to go and vice versa
Json-go - CLI to convert JSON to go and vice versa

Json To Go Struct CLI Install Go version 1.17 go install github.com/samit22/js

Jul 29, 2022
JSON Spanner - A Go package that provides a fast and simple way to filter or transform a json document

JSON SPANNER JSON Spanner is a Go package that provides a fast and simple way to

Sep 14, 2022
Copy of Golang's json library with IsZero feature

json Copy of Golang's json library with IsZero feature from CL13977 Disclaimer It is a package primary used for my own projects, I will keep it up-to-

Oct 9, 2021
library for working amorphous data (as when you decode json into an interface{})

Introduction Decoding json into an interface{} produces an hierarchical arrangement of four data types: float64, string are 'primative types' and form

Aug 1, 2022
A blazingly fast JSON serializing & deserializing library
A blazingly fast JSON serializing & deserializing library

Sonic A blazingly fast JSON serializing & deserializing library, accelerated by JIT(just-in-time compiling) and SIMD(single-instruction-multi-data). B

Jan 5, 2023
A library to query the godoc.org JSON API.

gopkg This repository provides minimal Go package that makes queries against the godoc.org JSON API. Since that site has mostly been subsumed by pkg.g

Dec 2, 2022
Fork of Go's standard library json encoder

A fork of the Go standard library's json encoder Why? https://github.com/golang/go/issues/6213 was proposed in 2013 but was never accepted. Difference

Nov 25, 2021