Packages

A JSON pull library for Erlang

Current section

Files

Jump to
jsonpull src jsonpull_expect.erl
Raw

src/jsonpull_expect.erl

% @doc These functions will read a value or error out immediately, with useful errorinfo applied on top.
%
% TODO: keep? remove?
-module(jsonpull_expect).
-export([
null/1,
boolean/1,
string/1,
iolist/1,
existing_atom/1,
number/1,
integer/1,
float/1,
array/1,
element/1,
object/1,
key/1
]).
-export([
format_error/2
]).
-define(WRAP(X),
X(Bin) when is_binary(Bin) ->
case jsonpull:X(Bin) of
{ok, V} -> V;
{error, E} -> erlang:error(E, [Bin], [{error_info, #{cause => E}}])
end;
X(Arg) -> erlang:error(badarg, [Arg], [{error_info, #{cause => not_binary}}])).
-spec null(JSON :: binary()) -> {null, Rest :: binary()}.
?WRAP(null).
-spec boolean(JSON :: binary()) -> {boolean, Rest :: binary()}.
?WRAP(boolean).
-spec string(JSON :: binary()) -> {binary(), Rest :: binary()}.
?WRAP(string).
-spec iolist(JSON :: binary()) -> {iolist(), Rest :: binary()}.
?WRAP(iolist).
-spec existing_atom(JSON :: binary()) -> {atom(), Rest :: binary()}.
?WRAP(existing_atom).
-spec number(JSON :: binary()) -> {binary(), Rest :: binary()}.
?WRAP(number).
-spec integer(JSON :: binary()) -> {integer(), Rest :: binary()}.
?WRAP(integer).
-spec float(JSON :: binary()) -> {float(), Rest :: binary()}.
?WRAP(float).
-spec array(JSON :: binary()) -> {begin_array, Rest :: binary()}.
?WRAP(array).
-spec element(JSON :: binary()) -> {element | end_array, Rest :: binary()}.
?WRAP(element).
-spec object(JSON :: binary()) -> {begin_object, Rest :: binary()}.
?WRAP(object).
-spec key(JSON :: binary()) -> {binary() | end_object, Rest :: binary()}.
?WRAP(key).
% @private
format_error(system_limit, _) -> #{};
format_error(_, [{_, F, As, Info}|_]) ->
ErrorInfoMap = proplists:get_value(error_info, Info, #{}),
Cause = maps:get(cause, ErrorInfoMap, none),
do_format_error(F, As, Cause).
do_format_error(_, _, not_binary) ->
#{ 1 => "should be a binary" };
do_format_error(_, _, not_null) ->
#{ reason => "the next value is not a null" };
do_format_error(_, _, not_boolean) ->
#{ reason => "the next value is not a boolean" };
do_format_error(_, _, not_string) ->
#{ reason => "the next value is not a string" };
do_format_error(_, _, unterminated_string) ->
#{ reason => "the string is missing one or more terminators" };
do_format_error(_, _, invalid_escape_sequence) ->
#{ reason => "the string contains an invalid escape sequence" };
do_format_error(_, _, not_existing_atom) ->
#{ reason => "not an already existing atom" };
do_format_error(_, _, not_number) ->
#{ reason => "the next value is not a number" };
do_format_error(_, _, not_integer) ->
#{ reason => "the next value is not an integer" };
do_format_error(_, _, not_float) ->
#{ reason => "the next value is not a float" };
do_format_error(_, _, not_array) ->
#{ reason => "the next value is not an array" };
do_format_error(_, _, not_object) ->
#{ reason => "the next value is not an object" };
do_format_error(_, _, missing_colon_after_key) ->
#{ reason => "there is no : following the key" };
do_format_error(_, _, unterminated_key) ->
#{ reason => "the key is missing one or more terminators" };
do_format_error(_, _, key_not_string) ->
#{ reason => "the key is not a string" }.