Current section

Files

Jump to
nextroll_erlcloud src erlcloud_json.erl
Raw

src/erlcloud_json.erl

-module(erlcloud_json).
-export([decode/2, decode/3]).
-include("erlcloud.hrl").
-type decode_return() :: [{Name :: atom(), Value :: string() | integer()}].
-type decode_value_type() :: optional_string | optional_integer | {optional_map, fun(([{Key :: binary(), Value :: string() | integer()}]) -> decode_return())}.
-type decode_value() :: {atom(), JsonField :: binary(), Type :: decode_value_type()}.
-type decode_value_r() :: {pos_integer(), JsonField :: binary(), Type :: atom()}.
-spec decode([decode_value()], proplist()) -> decode_return().
decode(Values, Json) ->
lists:foldr(
fun ({Name, JsonField, Type}, Output) ->
case get_value(JsonField, Type, Json) of
undefined -> Output;
Value ->
[{Name, Value} | Output]
end
end, [], Values).
-spec decode([decode_value_r()], proplist(), tuple()) -> tuple().
decode(Values, Json, Record) ->
lists:foldr(
fun ({Index, JsonField, Type}, Output) ->
case get_value(JsonField, Type, Json) of
undefined -> Output;
Value -> setelement(Index, Output, Value)
end
end, Record, Values).
get_value(JsonField, Type, Json) ->
case Type of
optional_string -> proplists:get_value(JsonField, Json, undefined);
optional_integer -> proplists:get_value(JsonField, Json, undefined);
string -> proplists:get_value(JsonField, Json, "");
integer -> proplists:get_value(JsonField, Json, 0);
Fun when is_function(Fun, 1) ->
Fun(proplists:get_value(JsonField, Json));
{optional_map, Fun} when is_function(Fun, 1) ->
case proplists:get_value(JsonField, Json, []) of
[] -> undefined;
List when is_list(List) -> lists:map(Fun, List)
end;
{map, Fun} when is_function(Fun, 1) ->
lists:map(Fun, proplists:get_value(JsonField, Json, []))
end.