• Stars
    star
    274
  • Rank 150,274 (Top 3 %)
  • Language
    Erlang
  • License
    MIT License
  • Created about 11 years ago
  • Updated almost 2 years 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

erldash

A simple, terminal-based Erlang dashboard written in Rust
Rust
133
star
3

erl_dist

Rust Implementation of Erlang Distribution Protocol
Rust
119
star
4

mineplacer

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

rustun

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

patricia_tree

A memory-efficient patricia tree implementation written in Rust
Rust
103
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

pixcil

Pixel art editor
Rust
70
star
10

eetf

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

efmt

Erlang code formatter
Rust
60
star
12

rustracing

OpenTracing API for Rust
Rust
60
star
13

mpeg2ts

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

wstcp

WebSocket to TCP proxy written in Rust
Rust
51
star
15

hls_m3u8

HLS(RFC8216) m3u8 parser/generator
Rust
51
star
16

mse_fmp4

A Rust library for generating fragmented MP4 that playable via Media Source Extensions
Rust
47
star
17

hash_ring

Implements consistent hashing in Erlang
Erlang
42
star
18

nowasm

No-std, no-unsafe and no-dependencies WebAssembly 1.0 runtime for Rust
Rust
39
star
19

evel

An Eventual Leader Election Library for Erlang
Erlang
36
star
20

sloggers

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

gomoku

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

pagurus

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

hyparview

A Rust implementation of HyParView algorithm
Rust
28
star
24

hls_wasm

WebAssembly HLS client written in Rust
Rust
27
star
25

stun_codec

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

plumcast

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

ekvsb

Benchmark Tool for Embedded Key-Value Stores available in Rust
Rust
26
star
28

plumtree

A Rust implementation of Plumtree algorithm
Rust
26
star
29

tpe

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

cl-asm

A x86 assembler in Commn Lisp
Common Lisp
24
star
31

bytecodec

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

rendezvous_hash

A Rust implementation of Rendezvous hashing algorithm
Rust
21
star
33

beam_file

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

igo-gae

Igo on Google App Engine
Java
21
star
35

prometrics

Rust client library for exposing prometheus metrics
Rust
21
star
36

erlls

Erlang language server
Rust
20
star
37

sanmoku

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

erl_rpc

Erlang RPC Client for Rust
Rust
19
star
39

hone

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

rtp

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

scalable_cuckoo_filter

A variant of Cuckoo Filter whose size automatically scales as necessary
Rust
17
star
42

ppg

Plumtree based Distributed Process Group
Erlang
17
star
43

splay_tree

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

ipc-msgque

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

taomp-sbcl

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

fanova

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

h264

H.264/AVC parser
Common Lisp
14
star
48

erl-splay-tree

A splay-tree implementation in Erlang
Erlang
13
star
49

local

A Local Name Registration Facility for Erlang
Erlang
12
star
50

beamcode

A Rust library to encode / decode Erlang BEAM instructions
Rust
11
star
51

cotoxy

TCP proxy which uses Consul for service discovery
Rust
10
star
52

handy_async

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

erl_ast

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

thrift_codec

Encoder and decoder for Thrift protocol written in Rust
Rust
10
star
55

raftbare

Minimal but feature-complete, I/O-free implementation of Raft distributed consensus algorithm for Rust.
Rust
10
star
56

evalrs

Rust code snippet evaluator
Rust
9
star
57

yamakan

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

amf

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

trackable

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

erl_parse

Erlang source code parser written in Rust
Rust
9
star
61

pagurus-snake-game-zig

Zig port of the example snake game of Pagurus.
Zig
8
star
62

rrsm

Raft based Replicated State Machine in Rust
Rust
8
star
63

serdeconv

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

logi

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

diagnoser

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

dagc

A Rust implementation of digital AGC (automatic gain control)
Rust
8
star
67

erl-rtmpmsg

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

jada

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

randomforest

A random forest implementation in Rust
Rust
8
star
70

sorastats

A terminal based viewer of WebRTC SFU Sora statistics
Rust
8
star
71

stun-zig

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

gen_cop

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

proxy

An Erlang Process Proxy Library
Erlang
7
star
74

fibers_rpc

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

protobuf_codec

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

rafte

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

fibers_http_server

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

erl_tokenize

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

pfun

Erlang Portable Functions
Erlang
7
star
80

nbchan

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

otp_passage

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

erl_pp

Erlang source code preprocessor written in Rust
Rust
6
star
83

jaeger_passage

Jaeger client library for Erlang
Erlang
6
star
84

erl-creole

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

kurobako-go

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

hamt

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

sais

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

hdf5file

A Rust implementation of HDF5 File Format
Rust
6
star
89

thrift_protocol

An Erlang implementation of Thrift protocol
Erlang
6
star
90

httpcodec

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

rtmp

Real Time Messaging Protocol
Common Lisp
6
star
92

cl-dawg

Direct Acyclic Word Graph
Common Lisp
5
star
93

ruby-dawg

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

epmd-zig

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

erl_pfds

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

flv_codec

FLV encoder/decoder based on bytecodec crate
Rust
5
star
97

linux_aio

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

passage

OpenTracing API for Erlang
Erlang
5
star
99

succ

Succinct Data Structures written in Rust
Rust
5
star
100

scalable_bloom_filter

A Rust implementation of Scalable Bloom Filters
Rust
5
star