2010-05-25 21:26:55 -07:00
|
|
|
%% The MIT License
|
|
|
|
|
2013-03-10 20:30:24 -07:00
|
|
|
%% Copyright (c) 2010-2013 alisdair sullivan <alisdairsullivan@yahoo.ca>
|
2010-05-25 21:26:55 -07:00
|
|
|
|
|
|
|
%% Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
%% of this software and associated documentation files (the "Software"), to deal
|
|
|
|
%% in the Software without restriction, including without limitation the rights
|
|
|
|
%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
%% copies of the Software, and to permit persons to whom the Software is
|
|
|
|
%% furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
%% The above copyright notice and this permission notice shall be included in
|
|
|
|
%% all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
%% THE SOFTWARE.
|
|
|
|
|
|
|
|
|
2010-05-18 13:01:49 -07:00
|
|
|
-module(jsx).
|
|
|
|
|
2012-05-23 21:57:01 -07:00
|
|
|
-export([encode/1, encode/2, decode/1, decode/2]).
|
2012-03-04 18:40:00 -08:00
|
|
|
-export([is_json/1, is_json/2, is_term/1, is_term/2]).
|
2012-05-12 23:28:48 +00:00
|
|
|
-export([format/1, format/2, minify/1, prettify/1]).
|
2012-05-23 06:47:58 -07:00
|
|
|
-export([encoder/3, decoder/3, parser/3]).
|
2013-03-05 21:10:33 -08:00
|
|
|
-export([resume/3]).
|
2011-11-29 19:56:00 -08:00
|
|
|
%% old api
|
2012-01-31 20:44:35 -08:00
|
|
|
-export([term_to_json/1, term_to_json/2, json_to_term/1, json_to_term/2]).
|
2012-05-23 21:57:01 -07:00
|
|
|
-export([to_json/1, to_json/2]).
|
|
|
|
-export([to_term/1, to_term/2]).
|
2013-03-05 20:02:52 -08:00
|
|
|
|
|
|
|
-export_type([json_term/0, json_text/0, token/0]).
|
|
|
|
-export_type([encoder/0, decoder/0, parser/0, internal_state/0]).
|
2011-11-23 20:54:10 -08:00
|
|
|
|
2012-11-06 08:30:00 -06:00
|
|
|
|
2011-11-23 20:54:10 -08:00
|
|
|
-ifdef(TEST).
|
2013-02-06 22:28:26 -08:00
|
|
|
-include("jsx_tests.hrl").
|
2011-11-23 20:54:10 -08:00
|
|
|
-endif.
|
2011-10-21 18:16:16 -07:00
|
|
|
|
|
|
|
|
2012-05-23 06:47:58 -07:00
|
|
|
-type json_term() :: list({binary(), json_term()})
|
|
|
|
| list(json_term())
|
2012-05-22 21:51:23 -07:00
|
|
|
| true
|
|
|
|
| false
|
|
|
|
| null
|
|
|
|
| integer()
|
|
|
|
| float()
|
|
|
|
| binary().
|
|
|
|
|
2012-05-23 06:47:58 -07:00
|
|
|
-type json_text() :: binary().
|
2010-09-15 21:30:25 -07:00
|
|
|
|
2012-05-23 06:47:58 -07:00
|
|
|
|
2013-01-22 12:41:56 -08:00
|
|
|
-spec encode(Source::json_term()) -> json_text() | {incomplete, encoder()}.
|
2013-02-12 11:54:42 -08:00
|
|
|
-spec encode(Source::json_term(), Config::jsx_to_json:config()) -> json_text() | {incomplete, encoder()}.
|
2011-11-23 20:54:10 -08:00
|
|
|
|
2012-05-23 21:57:01 -07:00
|
|
|
encode(Source) -> encode(Source, []).
|
2013-02-12 11:54:42 -08:00
|
|
|
encode(Source, Config) -> jsx_to_json:to_json(Source, Config).
|
2012-01-31 20:44:35 -08:00
|
|
|
|
2012-05-23 21:57:01 -07:00
|
|
|
%% old api, alias for encode/x
|
2012-03-05 20:37:22 -08:00
|
|
|
|
2012-05-23 21:57:01 -07:00
|
|
|
to_json(Source) -> encode(Source, []).
|
2013-02-12 11:54:42 -08:00
|
|
|
to_json(Source, Config) -> encode(Source, Config).
|
2012-05-23 21:57:01 -07:00
|
|
|
term_to_json(Source) -> encode(Source, []).
|
2013-02-12 11:54:42 -08:00
|
|
|
term_to_json(Source, Config) -> encode(Source, Config).
|
2011-10-21 18:16:16 -07:00
|
|
|
|
2011-10-24 22:51:39 -07:00
|
|
|
|
2013-01-22 12:41:56 -08:00
|
|
|
-spec format(Source::json_text()) -> json_text() | {incomplete, decoder()}.
|
2013-02-12 11:54:42 -08:00
|
|
|
-spec format(Source::json_text(), Config::jsx_to_json:config()) -> json_text() | {incomplete, decoder()}.
|
2011-11-29 19:56:00 -08:00
|
|
|
|
|
|
|
format(Source) -> format(Source, []).
|
2013-02-12 11:54:42 -08:00
|
|
|
format(Source, Config) -> jsx_to_json:format(Source, Config).
|
2011-11-29 19:56:00 -08:00
|
|
|
|
|
|
|
|
2013-01-22 12:41:56 -08:00
|
|
|
-spec minify(Source::json_text()) -> json_text() | {incomplete, decoder()}.
|
2012-05-12 23:28:48 +00:00
|
|
|
|
|
|
|
minify(Source) -> format(Source, []).
|
|
|
|
|
|
|
|
|
2013-01-22 12:41:56 -08:00
|
|
|
-spec prettify(Source::json_text()) -> json_text() | {incomplete, decoder()}.
|
2012-05-12 23:28:48 +00:00
|
|
|
|
|
|
|
prettify(Source) -> format(Source, [space, {indent, 2}]).
|
|
|
|
|
|
|
|
|
2013-01-22 12:41:56 -08:00
|
|
|
-spec decode(Source::json_text()) -> json_term() | {incomplete, decoder()}.
|
2013-02-12 11:54:42 -08:00
|
|
|
-spec decode(Source::json_text(), Config::jsx_to_term:config()) -> json_term() | {incomplete, decoder()}.
|
2012-03-25 00:26:12 -07:00
|
|
|
|
2012-05-23 21:57:01 -07:00
|
|
|
decode(Source) -> decode(Source, []).
|
2013-02-12 11:54:42 -08:00
|
|
|
decode(Source, Config) -> jsx_to_term:to_term(Source, Config).
|
2011-11-29 19:56:00 -08:00
|
|
|
|
2012-01-31 20:44:35 -08:00
|
|
|
%% old api, alias for to_term/x
|
2011-11-29 19:56:00 -08:00
|
|
|
|
2012-05-23 21:57:01 -07:00
|
|
|
to_term(Source) -> decode(Source, []).
|
2013-02-12 11:54:42 -08:00
|
|
|
to_term(Source, Config) -> decode(Source, Config).
|
2012-05-23 21:57:01 -07:00
|
|
|
json_to_term(Source) -> decode(Source, []).
|
2013-02-12 11:54:42 -08:00
|
|
|
json_to_term(Source, Config) -> decode(Source, Config).
|
2011-11-29 19:56:00 -08:00
|
|
|
|
|
|
|
|
2012-05-22 21:51:23 -07:00
|
|
|
-spec is_json(Source::any()) -> true | false.
|
2013-02-12 11:54:42 -08:00
|
|
|
-spec is_json(Source::any(), Config::jsx_verify:config()) -> true | false.
|
2011-11-23 20:54:10 -08:00
|
|
|
|
|
|
|
is_json(Source) -> is_json(Source, []).
|
2013-02-12 11:54:42 -08:00
|
|
|
is_json(Source, Config) -> jsx_verify:is_json(Source, Config).
|
2011-10-24 22:51:39 -07:00
|
|
|
|
|
|
|
|
2012-03-04 18:40:00 -08:00
|
|
|
-spec is_term(Source::any()) -> true | false.
|
2013-02-12 11:54:42 -08:00
|
|
|
-spec is_term(Source::any(), Config::jsx_verify:config()) -> true | false.
|
2012-03-04 18:40:00 -08:00
|
|
|
|
|
|
|
is_term(Source) -> is_term(Source, []).
|
2013-02-12 11:54:42 -08:00
|
|
|
is_term(Source, Config) -> jsx_verify:is_term(Source, Config).
|
2012-03-04 18:40:00 -08:00
|
|
|
|
|
|
|
|
2012-05-23 06:47:58 -07:00
|
|
|
-type decoder() :: fun((json_text() | end_stream) -> any()).
|
|
|
|
|
2013-02-12 11:54:42 -08:00
|
|
|
-spec decoder(Handler::module(), State::any(), Config::list()) -> decoder().
|
2012-03-04 15:46:41 -08:00
|
|
|
|
2013-02-12 11:54:42 -08:00
|
|
|
decoder(Handler, State, Config) -> jsx_decoder:decoder(Handler, State, Config).
|
2012-03-04 15:46:41 -08:00
|
|
|
|
|
|
|
|
2012-05-23 06:47:58 -07:00
|
|
|
-type encoder() :: fun((json_term() | end_stream) -> any()).
|
|
|
|
|
2013-02-12 11:54:42 -08:00
|
|
|
-spec encoder(Handler::module(), State::any(), Config::list()) -> encoder().
|
2012-03-04 15:46:41 -08:00
|
|
|
|
2013-02-12 11:54:42 -08:00
|
|
|
encoder(Handler, State, Config) -> jsx_encoder:encoder(Handler, State, Config).
|
2012-03-04 15:46:41 -08:00
|
|
|
|
|
|
|
|
2012-05-23 06:47:58 -07:00
|
|
|
-type token() :: [token()]
|
|
|
|
| start_object
|
|
|
|
| end_object
|
|
|
|
| start_array
|
|
|
|
| end_array
|
|
|
|
| {key, binary()}
|
|
|
|
| {string, binary()}
|
|
|
|
| binary()
|
|
|
|
| {number, integer() | float()}
|
|
|
|
| {integer, integer()}
|
|
|
|
| {float, float()}
|
|
|
|
| integer()
|
|
|
|
| float()
|
|
|
|
| {literal, true}
|
|
|
|
| {literal, false}
|
|
|
|
| {literal, null}
|
|
|
|
| true
|
|
|
|
| false
|
|
|
|
| null
|
|
|
|
| end_json.
|
2012-11-06 08:30:00 -06:00
|
|
|
|
2012-05-23 06:47:58 -07:00
|
|
|
|
|
|
|
-type parser() :: fun((token() | end_stream) -> any()).
|
|
|
|
|
2013-02-12 11:54:42 -08:00
|
|
|
-spec parser(Handler::module(), State::any(), Config::list()) -> parser().
|
2012-05-23 06:47:58 -07:00
|
|
|
|
2013-03-05 20:02:52 -08:00
|
|
|
parser(Handler, State, Config) -> jsx_parser:parser(Handler, State, Config).
|
|
|
|
|
|
|
|
-opaque internal_state() :: tuple().
|
|
|
|
|
2013-03-05 21:10:33 -08:00
|
|
|
-spec resume(Term::json_text() | token(), InternalState::internal_state(), Config::list()) -> any().
|
2013-03-05 20:02:52 -08:00
|
|
|
|
|
|
|
resume(Term, {decoder, State, Handler, Acc, Stack}, Config) ->
|
2013-03-06 01:37:08 -08:00
|
|
|
jsx_decoder:resume(Term, State, Handler, Acc, Stack, jsx_config:parse_config(Config));
|
2013-03-05 21:10:33 -08:00
|
|
|
resume(Term, {parser, State, Handler, Stack}, Config) ->
|
2013-03-06 01:37:08 -08:00
|
|
|
jsx_parser:resume(Term, State, Handler, Stack, jsx_config:parse_config(Config)).
|