SkillAgentSearch skills...

Jsx

an erlang application for consuming, producing and manipulating json. inspired by yajl

Install / Use

/learn @talentdeficit/Jsx
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

jsx (v3.0.0)

an erlang application for consuming, producing and manipulating [json][json]. inspired by [yajl][yajl]

jsx is built via [rebar3][rebar3]

current status:

jsx is released under the terms of the [MIT][MIT] license

copyright 2010-2016 alisdair sullivan

index

quickstart

to add to a rebar3 project

Add to rebar.config

...
{erl_opts, [debug_info]}.
{deps, [
       ...
       {jsx, "~> 3.0"}
]}.
...

to build the library and run tests

$ rebar3 compile
$ rebar3 eunit

to convert a utf8 binary containing a json string into an erlang term

1> jsx:decode(<<"{\"library\": \"jsx\", \"awesome\": true}">>, []).
#{<<"awesome">> => true,<<"library">> => <<"jsx">>}
2> jsx:decode(<<"{\"library\": \"jsx\", \"awesome\": true}">>, [{return_maps, false}]).
[{<<"library">>,<<"jsx">>},{<<"awesome">>,true}]
3> jsx:decode(<<"[\"a\",\"list\",\"of\",\"words\"]">>).
[<<"a">>, <<"list">>, <<"of">>, <<"words">>]

to convert an erlang term into a utf8 binary containing a json string

1> jsx:encode(#{<<"library">> => <<"jsx">>, <<"awesome">> => true}).
<<"{\"awesome\":true,\"library\":\"jsx\"}">>
2> jsx:encode([{<<"library">>,<<"jsx">>},{<<"awesome">>,true}]).
<<"{\"library\": \"jsx\", \"awesome\": true}">>
3> jsx:encode([<<"a">>, <<"list">>, <<"of">>, <<"words">>]).
<<"[\"a\",\"list\",\"of\",\"words\"]">>

to check if a binary or a term is valid json

1> jsx:is_json(<<"[\"this is json\"]">>).
true
2> jsx:is_json("[\"this is not\"]").
false
3> jsx:is_term([<<"this is a term">>]).
true
4> jsx:is_term([this, is, not]).
false

to minify some json

1> jsx:minify(<<"{
  \"a list\": [
    1,
    2,
    3
  ]
}">>).
<<"{\"a list\":[1,2,3]}">>

to prettify some json

1> jsx:prettify(<<"{\"a list\":[1,2,3]}">>).
<<"{
  \"a list\": [
    1,
    2,
    3
  ]
}">>

description

jsx is an erlang application for consuming, producing and manipulating [json][json]

jsx follows the json [spec][rfc4627] as closely as possible with allowances for real world usage

jsx is pragmatic. the json spec allows extensions so jsx extends the spec in a number of ways. see the section on strict in options below though

json has no official comments but this parser allows c/c++ style comments. anywhere whitespace is allowed you can insert comments (both // ... and /* ... */)

some particularly irresponsible json emitters leave trailing commas at the end of objects or arrays. jsx allows a single trailing comma in input. multiple commas in any position or a preceding comma are still errors

all jsx decoder input should be utf8 encoded binaries. sometimes you get binaries that are almost but not quite valid utf8 whether due to improper escaping or poor encoding. jsx replaces invalid codepoints and poorly formed sequences with the unicode replacement character (u+FFFD) but does it's best to return something comprehensible

json only allows keys and strings to be delimited by double quotes (u+0022) but javascript allows them to be delimited by single quotes (u+0027) as well. jsx follows javascript in this. strings that start with single quotes can contain double quotes but must end with single quotes and must escape any single quotes they contain

json and jsx only recognize escape sequences as outlined in the json spec. it just ignores bad escape sequences leaving them in strings unaltered

json <-> erlang mapping

json | erlang --------------------------------|-------------------------------- number | integer() and float() string | binary() and atom() true, false and null | true, false and null array | [] and [JSON] object | #{}, [{}] and [{binary() OR atom() OR integer(), JSON}] see below | datetime()

  • numbers

    javascript and thus json represent all numeric values with floats. there's no reason for erlang -- a language that supports arbitrarily large integers -- to restrict all numbers to the ieee754 range

    whenever possible, jsx will interpret json numbers that look like integers as integers. other numbers will be converted to erlang's floating point type, which is nearly but not quite iee754. negative zero is not representable in erlang (zero is unsigned in erlang and 0 is equivalent to -0) and will be interpreted as regular zero. numbers not representable are beyond the concern of this implementation, and will result in parsing errors

    when converting from erlang to json, floats are represented with their shortest representation that will round trip without loss of precision. this means that some floats may be superficially dissimilar (although functionally equivalent). for example, 1.0000000000000001 will be represented by 1.0

  • strings

    json strings must be unicode encoded binaries or erlang atoms. in practice, because jsx only accepts utf8 binaries all binary strings must be utf8. in addition to being unicode json strings restrict a number of codepoints and define a number of escape sequences

    json string escapes of the form \uXXXX will be converted to their equivalent codepoints during parsing. this means control characters and other codepoints disallowed by the json spec may be encountered in resulting strings. the utf8 restriction means the surrogates are explicitly disallowed. if a string contains escaped surrogates (u+d800 to u+dfff) they are interpreted but only when they form valid surrogate pairs. surrogates encountered otherwise are replaced with the replacement codepoint (u+fffd)

    all erlang strings are represented by valid utf8 encoded binaries. the encoder will check strings for conformance. badly formed utf8 sequences may be replaced with the replacement codepoint (u+fffd) according to the unicode spec

    this implementation performs no normalization on strings beyond that detailed here. be careful when comparing strings as equivalent strings may have different utf8 encodings

  • true, false and null

    the json primitives true, false and null are represented by the erlang atoms true, false and null. surprise

  • arrays

    json arrays are represented with erlang lists of json values as described in this section

  • objects

    json objects are represented by erlang maps.

  • datetime

    erlang datetime tuples ({{Year, Month, Day}, {Hour, Min, Sec}}) as returned from erlang:localtime/0 are automatically encoded as [iso8601][iso8601] strings and are assumed to be UTC time. no conversion is attempted of json [iso8601][iso8601] strings in decoded json

incomplete input

jsx can handle incomplete json texts. if the option stream is passed to the decoder or parser and if a partial json text is parsed, rather than returning a term from your callback handler, jsx returns {incomplete, F} where F is a function with an identical API to the anonymous fun returned from decoder/3, encoder/3 or parser/3. it retains the internal state of the parser at the point where input was exhausted. this allows you to parse as you stream json over a socket or file descriptor, or to parse large json texts without needing to keep them entirely in memory

however, it is important to recognize that jsx is conservative by default. jsx will not consider the parsing complete even when input is exhausted and the json text is unambiguously incomplete. to end parsing call the incomplete function with the argument end_stream (or end_json) like:

1> {incomplete, F} = jsx:decode(<<"[">>, [stream]).
{incomplete,#Fun<jsx_decoder.1.122947756>}
2> F(end_stream).  % can also be `F(end_json)`
** exception error: bad argument
3> {incomplete, G} = F(<<"]">>).
{incomplete,#Fun<jsx_decoder.1.122947756>}
4> G(end_stream).  % can also be `G(end_json)`
[]

data types

json_term()

json_term() = [json_term()]
    | [{binary() | atom() | integer(), json_term()}]
    | #{} % map of any size, not just the empty map
    | true
    | false
    | null
    | integer()
    | float()
    | binary()
    | atom()
		| datetime()

the erlang representation of json. binaries should be utf8 encoded, or close at least

json_text()

json_text() = binary()

a utf8 encoded binary containing a json string

event()

event() = start_object
    | end_object
    | start_array
    | end_array
    | {key, binary()}
    | {string, binary()}
    | {integer, integer()}
    | {float, float()}
    | {literal, true}
    | {literal, false}
    | {literal, null}
    | end_json

the subset of token() emitted by th

View on GitHub
GitHub Stars697
CategoryDevelopment
Updated9d ago
Forks217

Languages

Erlang

Security Score

100/100

Audited on Mar 19, 2026

No findings