• Stars
    star
    274
  • Rank 144,794 (Top 3 %)
  • Language
    Erlang
  • License
    MIT License
  • Created over 10 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Erlang JSON library

jsone

hex.pm version Build Status Code Coverage License: MIT

An Erlang library for encoding, decoding JSON data.

Features

  • Provides simple encode/decode function only
  • RFC7159-compliant
  • Supports UTF-8 encoded binary
  • Pure Erlang
  • Highly Efficient
    • Maybe one of the fastest JSON library (except those which are implemented in NIF)
    • Decode function is written in continuation-passing style(CPS)

QuickStart

# clone
$ git clone git://github.com/sile/jsone.git
$ cd jsone

# compile
$ make compile

# run tests
$ make eunit

# dialyze
$ make dialyze

# Erlang shell
$ make start
1> jsone:decode(<<"[1,2,3]">>).
[1,2,3]

Enable HiPE

If you want to use HiPE compiled version, please add following code to your rebar.config.

{overrides,
  [
    {override, jsone, [{erl_opts, [{d, 'ENABLE_HIPE'}, inline]}]}
  ]}.

or use native profile. The make command supports profile as well. For example:

$ make start profile=native

Usage Example

%% Decode
> jsone:decode(<<"[1,2,3]">>).
[1,2,3]

> jsone:decode(<<"{\"1\":2}">>).
#{<<"1">> => 2}

> jsone:decode(<<"{\"1\":2}">>, [{object_format, tuple}]). % tuple format
{[{<<"1">>, 2}]}

> jsone:decode(<<"{\"1\":2}">>, [{object_format, proplist}]). % proplist format
[{<<"1">>, 2}]

> jsone:try_decode(<<"[1,2,3] \"next value\"">>). % try_decode/1 returns remaining (unconsumed binary)
{ok,[1,2,3],<<" \"next value\"">>}

% error: raises exception
> jsone:decode(<<"1.x">>).
** exception error: bad argument
     in function  jsone_decode:number_fraction_part_rest/6
        called as jsone_decode:number_fraction_part_rest(<<"x">>,1,1,0,[],<<>>)
     in call from jsone:decode/1 (src/jsone.erl, line 71)

% error: returns {error, Reason}
> jsone:try_decode(<<"1.x">>).
{error,{badarg,[{jsone_decode,number_fraction_part_rest,
                              [<<"x">>,1,1,0,[],<<>>],
                              [{line,228}]}]}}


%% Encode
> jsone:encode([1,2,3]).
<<"[1,2,3]">>

> jsone:encode(#{<<"key">> => <<"value">>}).  % map format
> jsone:encode({[{<<"key">>, <<"value">>}]}). % tuple format
> jsone:encode([{<<"key">>, <<"value">>}]).  % proplist format
<<"{\"key\":\"value\"}">>

> jsone:encode(#{key => <<"value">>}). % atom key is allowed
<<"{\"key\":\"value\"}">>

% error: raises exception
> jsone:encode(#{123 => <<"value">>}). % non binary|atom key is not allowed
** exception error: bad argument
     in function  jsone_encode:object_members/3
        called as jsone_encode:object_members([{123,<<"value">>}],[],<<"{">>)
     in call from jsone:encode/1 (src/jsone.erl, line 97)

% error: returns {error, Reason}
> jsone:try_encode({[{123, <<"value">>}]}).
{error,{badarg,[{jsone_encode,object_members,
                              [[{123,<<"value">>}],[],<<"{">>],
                              [{line,138}]}]}}

% 'object_key_type' option allows non-string object key
> jsone:encode({[{123, <<"value">>}]}, [{object_key_type, scalar}]).
<<"{\"123\":\"value\"}">>

% 'undefined_as_null' option allows encoding atom undefined as null
> jsone:encode(undefined,[undefined_as_null]).
<<"null">>

%% Pretty Print
> Data = [true, #{<<"1">> => 2, <<"array">> => [[[[1]]], #{<<"ab">> => <<"cd">>}, [], #{}, false]}, null].
> io:format("~s\n", [jsone:encode(Data, [{indent, 2}, {space, 1}])]).
[
  true,
  {
    "1": 2,
    "array": [
      [
        [
          [
            1
          ]
        ]
      ],
      {
        "ab": "cd"
      },
      [],
      {},
      false
    ]
  },
  null
]
ok

%% Number Format
> jsone:encode(1). % integer
<<"1">>

> jsone:encode(1.23). % float
<<"1.22999999999999998224e+00">> % default: scientific notation

> jsone:encode(1.23, [{float_format, [{decimals, 4}]}]). % decimal notation
<<"1.2300">>

> jsone:encode(1.23, [{float_format, [{decimals, 4}, compact]}]). % compact decimal notation
<<"1.23">>

%% If you want to safely cast object keys to atoms, the `attempt_atom' option will help.
> jsone:decode(<<"{\"hello\": \"world\"}">>, [{keys, attempt_atom}]).
#{<<"hello">> => <<"world">>}  % There is no atom named "hello", so the key is decoded as binary.

> hello.  % Create "hello" atom.
hello

> jsone:decode(<<"{\"hello\": \"world\"}">>, [{keys, attempt_atom}]).
#{hello => <<"world">>} % Now, the key is decoded as atom.

Data Mapping (Erlang <=> JSON)

Erlang                  JSON             Erlang
=================================================================================================

null                   -> null                       -> null
undefined              -> null                       -> undefined                  % undefined_as_null
true                   -> true                       -> true
false                  -> false                      -> false
<<"abc">>              -> "abc"                      -> <<"abc">>
abc                    -> "abc"                      -> <<"abc">> % non-special atom is regarded as a binary
{{2010,1,1},{0,0,0}}   -> "2010-01-01T00:00:00Z"     -> <<"2010-01-01T00:00:00Z">>     % datetime*
{{2010,1,1},{0,0,0.0}} -> "2010-01-01T00:00:00.000Z" -> <<"2010-01-01T00:00:00.000Z">> % datetime*
123                    -> 123                        -> 123
123.4                  -> 123.4                      -> 123.4
[1,2,3]                -> [1,2,3]                    -> [1,2,3]
{[]}                   -> {}                         -> {[]}                       % object_format=tuple
{[{key, <<"val">>}]}   -> {"key":"val"}              -> {[{<<"key">>, <<"val">>}]} % object_format=tuple
[{}]                   -> {}                         -> [{}]                       % object_format=proplist
[{<<"key">>, val}]     -> {"key":"val"}              -> [{<<"key">>, <<"val">>}]   % object_format=proplist
#{}                    -> {}                         -> #{}                        % object_format=map
#{key => val}          -> {"key":"val"}              -> #{<<"key">> => <<"val">>}  % object_format=map
{{json, IOList}}       -> Value                      -> ~~~                        % UTF-8 encoded term**
{{json_utf8, Chars}}   -> Value                      -> ~~~                        % Unicode code points**

* see jsone:datetime_encode_format()

** {json, IOList} and {json_utf8, Chars} allows inline already encoded JSON values. For example, you obtain JSON encoded data from database so you don't have to decode it first and encode again. See jsone:json_term().

API

See EDoc Document

Benchmark

The results of poison benchmarking.

See the benchmark/README.md file for more information.

Encoding (Unit: IPS=inputs per second)

Input data \ Library Jason jiffy JSON* jsone JSX Poison Tiny
Blockchain 2.77 K 4.55 K 0.45 K 1.44 K (3) 0.60 K 1.30 K 0.99 K
Giphy 230.65 487.67 47.73 114.57 (4) 44.97 114.57 113.59
GitHub 880.03 1566.67 139.79 300.26 (5) 99.68 424.75 455.07
GovTrack 6.57 24.92 2.33 5.35 (5) 2.65 7.06 7.86
Issue 90 22.80 21.92 0.77 14.30 (3) 5.33 12.60 12.95
JSON Generateor 200.40 606.81 42.45 147.12 (4) 68.73 187.95 123.93
Pokedex 209.51 776.67 62.60 161.45 (4) 69.87 190.93 125.16
UTF-8 unescaped 626.25 6644.53 1167.89 582.41 (4) 273.48 401.44 220.14

* Only JSON didn't escape non-ASCII unicode characters on the encoding

Decoding (Unit: IPS=inputs per second)

Input data \ Library Jason jiffy JSON jsone JSX Poison Tiny
Blockchain 2.75 K 2.62 K 0.35 K 2.21 K (3) 0.89 K 1.32 K 1.49 K
Giphy 212.18 243.45 35.67 109.11 (5) 64.32 110.76 114.54
GitHub 973.41 1052.94 137.02 662.39 (3) 271.97 438.79 542.67
GovTrack 10.77 8.32 0.80 5.08 (3) 2.81 3.58 3.65
Issue 90 17.85 41.16 0.88 10.79 (5) 6.02 13.63 14.03
JSON Generateor 320.79 243.93 25.16 184.23 (3) 111.24 135.47 139.78
JSON Generateor (Pretty) 273.57 205.09 25.04 158.82 (3) 97.93 123.31 136.65
Pokedex 527.63 285.43 33.70 245.36 (3) 140.90 172.45 152.59
UTF-8 escaped 1224.48 7923.08 326.43 573.70 (4) 550.36 918.21 520.31
UTF-8 unescaped 5.56 K 12.54 K 1.35 K 5.09 K (3) 3.30 K 4.39 K 1.46 K

License

This library is released under the MIT License.

See the COPYING file for full license information.

More Repositories

1

libflate

A Rust implementation of DEFLATE algorithm and related formats (ZLIB, GZIP)
Rust
159
star
2

erl_dist

Rust Implementation of Erlang Distribution Protocol
Rust
119
star
3

mineplacer

Prepare for a game of Minesweeper by placing mines!
Rust
118
star
4

rustun

A Rust library for implementing STUN server and client asynchronously
Rust
111
star
5

erldash

A simple, terminal-based Erlang dashboard written in Rust
Rust
105
star
6

patricia_tree

A memory-efficient patricia tree implementation written in Rust
Rust
100
star
7

rusturn

A Rust Implementation of TURN server and client
Rust
98
star
8

rustracing_jaeger

Jaeger tracing library for Rust
Rust
83
star
9

eetf

A Rust implementation of Erlang External Term Format
Rust
65
star
10

pixcil

Pixel art editor
Rust
63
star
11

efmt

Erlang code formatter
Rust
60
star
12

rustracing

OpenTracing API for Rust
Rust
59
star
13

mpeg2ts

MPEG2-TS decoding/encoding library for Rust
Rust
51
star
14

hls_m3u8

HLS(RFC8216) m3u8 parser/generator
Rust
48
star
15

mse_fmp4

A Rust library for generating fragmented MP4 that playable via Media Source Extensions
Rust
45
star
16

hash_ring

Implements consistent hashing in Erlang
Erlang
42
star
17

wstcp

WebSocket to TCP proxy written in Rust
Rust
41
star
18

evel

An Eventual Leader Election Library for Erlang
Erlang
36
star
19

sloggers

A Rust library which provides frequently used slog loggers and convenient functions
Rust
33
star
20

gomoku

A self-contained morphological analyzer (including dictionary data).
Common Lisp
33
star
21

hyparview

A Rust implementation of HyParView algorithm
Rust
28
star
22

plumcast

A message broadcasting library based on the Plumtree/HyParView algorithms
Rust
27
star
23

plumtree

A Rust implementation of Plumtree algorithm
Rust
26
star
24

hls_wasm

WebAssembly HLS client written in Rust
Rust
25
star
25

tpe

A TPE (Tree-structured Parzen Estimator) implementation in Rust
Rust
25
star
26

stun_codec

Decoders and encoders for STUN (RFC 5389) and its extensions
Rust
24
star
27

cl-asm

A x86 assembler in Commn Lisp
Common Lisp
24
star
28

bytecodec

A tiny Rust framework for implementing encoders/decoders of byte-oriented protocols
Rust
23
star
29

pagurus

🐚+🦞 Ultra-portable Rust game engine suited for offline 2D games powered by WebAssembly
Rust
23
star
30

ekvsb

Benchmark Tool for Embedded Key-Value Stores available in Rust
Rust
22
star
31

rendezvous_hash

A Rust implementation of Rendezvous hashing algorithm
Rust
21
star
32

beam_file

A tiny library for processing Erlang BEAM file in Rust
Rust
21
star
33

igo-gae

Igo on Google App Engine
Java
21
star
34

prometrics

Rust client library for exposing prometheus metrics
Rust
21
star
35

erlls

Erlang language server
Rust
20
star
36

sanmoku

A morphological analyzer with a small memory footprint.
Common Lisp
19
star
37

hone

A shell-friendly hyperparameter search tool inspired by Optuna
Rust
18
star
38

rtp

A Rust implementation of RTP and profiles derived from it.
Rust
17
star
39

ppg

Plumtree based Distributed Process Group
Erlang
17
star
40

splay_tree

Splay Tree based Collections (e.g., Map, Set, Heap) Library for Rust
Rust
17
star
41

erl_rpc

Erlang RPC Client for Rust
Rust
17
star
42

scalable_cuckoo_filter

A variant of Cuckoo Filter whose size automatically scales as necessary
Rust
15
star
43

ipc-msgque

Lock-Free message queue for IPC
C++
15
star
44

taomp-sbcl

A lisp(sbcl) implementation of the algorithms described in 『The Art of Multiprocessor Programming』
Common Lisp
15
star
45

fanova

A Rust implementation of fANOVA (functional analysis of variance)
Rust
14
star
46

h264

H.264/AVC parser
Common Lisp
14
star
47

erl-splay-tree

A splay-tree implementation in Erlang
Erlang
13
star
48

local

A Local Name Registration Facility for Erlang
Erlang
12
star
49

beamcode

A Rust library to encode / decode Erlang BEAM instructions
Rust
12
star
50

handy_async

A handy Rust library for describing asynchronous code declaratively
Rust
10
star
51

erl_ast

A Rust library for working with Abstract Syntax Trees of Erlang programs
Rust
10
star
52

cotoxy

TCP proxy which uses Consul for service discovery
Rust
9
star
53

evalrs

Rust code snippet evaluator
Rust
9
star
54

yamakan

A collection of Black-Box Optimization algorithms for Rust
Rust
9
star
55

amf

A Rust Implementation of AMF (Action Media Format)
Rust
9
star
56

erl_parse

Erlang source code parser written in Rust
Rust
9
star
57

trackable

Rust library provides a way to track objects manually as an alternative to mechanisms like backtracing
Rust
9
star
58

thrift_codec

Encoder and decoder for Thrift protocol written in Rust
Rust
9
star
59

rrsm

Raft based Replicated State Machine in Rust
Rust
8
star
60

serdeconv

A Rust library that facilitates the conversion between TOML/JSON/MessagePack strings and serializable values
Rust
8
star
61

logi

A Logger Interface Library for Erlang/OTP
Erlang
8
star
62

diagnoser

Yet another implementation of Erlang's Dialyzer written in Rust
Rust
8
star
63

erl-rtmpmsg

An Erlang library to encode/decode RTMP message
Erlang
8
star
64

jada

A Java implementation of DoubleArray-Trie.
Java
8
star
65

stun-zig

Zig implementation of STUN protocol (RFC 5389)
Zig
8
star
66

gen_cop

Generic Connection-Oriented Protocol Behaviour (experimentail)
Erlang
8
star
67

proxy

An Erlang Process Proxy Library
Erlang
7
star
68

pagurus-snake-game-zig

Zig port of the example snake game of Pagurus.
Zig
7
star
69

fibers_rpc

Rust RPC library built on top of fibers crate
Rust
7
star
70

protobuf_codec

A Rust implementation of encoders and decoders for Protocol Buffers
Rust
7
star
71

rafte

An Erlang implementation of the Raft consensus algorithm
Erlang
7
star
72

fibers_http_server

A tiny HTTP/1.1 server framework for Rust
Rust
7
star
73

erl_tokenize

An Erlang source code tokenizer written in Rust.
Rust
7
star
74

pfun

Erlang Portable Functions
Erlang
7
star
75

dagc

A Rust implementation of digital AGC (automatic gain control)
Rust
7
star
76

nbchan

Highly optimized non-blocking communication channels implemented in Rust
Rust
6
star
77

otp_passage

OpenTracing instrumentation library for the Erlang/OTP standard modules
Erlang
6
star
78

jaeger_passage

Jaeger client library for Erlang
Erlang
6
star
79

erl_pp

Erlang source code preprocessor written in Rust
Rust
6
star
80

erl-creole

Converting strings between multibyte encodings and Unicode.
Erlang
6
star
81

hamt

An implementatin of Hash Array Mapped Trie.
Common Lisp
6
star
82

kurobako-go

A Golang library to help implement kurobako's solvers and problems
Go
6
star
83

sais

An implementation of SA-IS algorithm.
C++
6
star
84

hdf5file

A Rust implementation of HDF5 File Format
Rust
6
star
85

randomforest

A random forest implementation in Rust
Rust
6
star
86

sorastats

A terminal based viewer of WebRTC SFU Sora statistics
Rust
6
star
87

rtmp

Real Time Messaging Protocol
Common Lisp
6
star
88

cl-dawg

Direct Acyclic Word Graph
Common Lisp
5
star
89

ruby-dawg

Direct-Acyclic-Word-Graph for Ruby
5
star
90

erl_pfds

An Erlang implementation of the data structures described in 『Purely Functional Data Structures』
Erlang
5
star
91

epmd-zig

EPMD (Erlang Port Mapper Daemon) client in Zig
Zig
5
star
92

charseq

Common Lisp
5
star
93

linux_aio

A thin Rust wrapper on top of the Linux AIO API
Rust
5
star
94

passage

OpenTracing API for Erlang
Erlang
5
star
95

succ

Succinct Data Structures written in Rust
Rust
5
star
96

scalable_bloom_filter

A Rust implementation of Scalable Bloom Filters
Rust
5
star
97

consistent_hash

A Rust implementation of Consistent hashing algorithm
Rust
5
star
98

thrift_protocol

An Erlang implementation of Thrift protocol
Erlang
5
star
99

erl-amf

An Erlang library to encode/decode AMF
Erlang
5
star
100

httpcodec

Encoders and decoders for HTTP/1.x messages based on bytecodec crate.
Rust
5
star