summaryrefslogtreecommitdiff
path: root/deps/rabbitmq_aws/src/rabbitmq_aws_json.erl
blob: 5b4e3b2f45978ce284ade90e3aea091dcd207e9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
%% ====================================================================
%% @author Gavin M. Roy <gavinmroy@gmail.com>
%% @copyright 2016, Gavin M. Roy
%% @doc Wrap a JSON parser to provide easy abstractions across
%%      implementations and ensure a consistent return interface.
%% @end
%% ====================================================================
-module(rabbitmq_aws_json).

-export([decode/1]).

-spec decode(Value :: string() | binary()) -> list().
%% @doc Decode a JSON string returning a proplist
%% @end
decode(Value) when is_list(Value) ->
  decode(list_to_binary(Value));
decode(Value) when is_binary(Value) ->
  % We set an empty list of options because we don't want the default
  % options set in rabbit_json:cecode/1. And we can't override
  % 'return_maps' with '{return_maps, false}' because of a bug in jsx's
  % options handler.
  % See https://github.com/talentdeficit/jsx/pull/115
  Decoded0 = rabbit_json:decode(Value, []),
  Decoded = if
    is_map(Decoded0)  -> maps:to_list(Decoded0);
    is_list(Decoded0) -> Decoded0
  end,
  convert_binary_values(Decoded, []).


-spec convert_binary_values(Value :: list(), Accumulator :: list()) -> list().
%% @doc Convert the binary key/value pairs returned by rabbit_json to strings.
%% @end
convert_binary_values([], Value) ->  Value;
convert_binary_values([{K, V}|T], Accum) when is_map(V) ->
  convert_binary_values(
    T,
    lists:append(
      Accum,
      [{binary_to_list(K), convert_binary_values(maps:to_list(V), [])}]));
convert_binary_values([{K, V}|T], Accum) when is_list(V) ->
  convert_binary_values(
    T,
    lists:append(
      Accum,
      [{binary_to_list(K), convert_binary_values(V, [])}]));
convert_binary_values([{}|T],Accum) ->
  convert_binary_values(T, lists:append(Accum, [{}]));
convert_binary_values([{K, V}|T], Accum) when is_binary(V) ->
  convert_binary_values(T, lists:append(Accum, [{binary_to_list(K), binary_to_list(V)}]));
convert_binary_values([{K, V}|T], Accum) ->
  convert_binary_values(T, lists:append(Accum, [{binary_to_list(K), V}]));
convert_binary_values([H|T], Accum) when is_map(H) ->
  convert_binary_values(T, lists:append(Accum, convert_binary_values(maps:to_list(H), [])));
convert_binary_values([H|T], Accum) when is_binary(H) ->
  convert_binary_values(T, lists:append(Accum, [binary_to_list(H)]));
convert_binary_values([H|T], Accum) when is_integer(H) ->
  convert_binary_values(T, lists:append(Accum, [H]));
convert_binary_values([H|T], Accum) when is_atom(H) ->
  convert_binary_values(T, lists:append(Accum, [H]));
convert_binary_values([H|T], Accum) ->
  convert_binary_values(T, lists:append(Accum, convert_binary_values(H, []))).