|
@@ -17,18 +17,47 @@
|
|
|
|
|
|
-define(JSONB_VERSION_1, 1).
|
|
-define(JSONB_VERSION_1, 1).
|
|
|
|
|
|
-%% TODO: JSON encode/decode `fun Mod:Name/1` / `{Mod, Name}` as option.
|
|
|
|
-%% Shall not pass `fun(_) -> .. end`, because of hot code upgrade problems.
|
|
|
|
-init(_, _) -> [].
|
|
|
|
|
|
+%% JsonMod shall either be a module with encode/1 and decode/1, where:
|
|
|
|
+%%
|
|
|
|
+%% - encode/1 expects erlang-formatted JSON, e.g. a map or a proplist,
|
|
|
|
+%% and returns a valid JSON binary string.
|
|
|
|
+%% - decode/1 expects a valid JSON binary string, and returns erlang-formatted JSON.
|
|
|
|
+%%
|
|
|
|
+%% or a tuple {Mod, {encode, Opts}, {decode, Opts}} where Mod implements encode/2 and
|
|
|
|
+%% decode/2 with the same interface semantics as encode/1 and decode/1, while
|
|
|
|
+%% accepting Opts as options to pass into the encode/2 and decode/2 functions.
|
|
|
|
+%%
|
|
|
|
+%% Tip: if you require special behavior that a third-party JSON module doesn't provide
|
|
|
|
+%% for you, or which doesn't strictly meet this interface requirement, wrap the
|
|
|
|
+%% third-party JSON module in a new module that implements the required interface,
|
|
|
|
+%% and pass in _that_ as JsonMod.
|
|
|
|
+init(JsonMod, _) ->
|
|
|
|
+ JsonMod.
|
|
|
|
|
|
names() ->
|
|
names() ->
|
|
[json, jsonb].
|
|
[json, jsonb].
|
|
|
|
|
|
|
|
+encode(ErlJson, json, JsonMod) when is_atom(JsonMod) ->
|
|
|
|
+ JsonMod:encode(ErlJson);
|
|
|
|
+encode(ErlJson, json, {JsonMod, {encode, Opts}, _}) when is_atom(JsonMod) ->
|
|
|
|
+ JsonMod:encode(ErlJson, Opts);
|
|
|
|
+encode(ErlJson, jsonb, JsonMod) when is_atom(JsonMod) ->
|
|
|
|
+ <<?JSONB_VERSION_1:8, (JsonMod:encode(ErlJson))/binary>>;
|
|
|
|
+encode(ErlJson, jsonb, {JsonMod, {encode, Opts}, _}) when is_atom(JsonMod) ->
|
|
|
|
+ <<?JSONB_VERSION_1:8, (JsonMod:encode(ErlJson, Opts))/binary>>;
|
|
encode(Bin, json, _) ->
|
|
encode(Bin, json, _) ->
|
|
Bin;
|
|
Bin;
|
|
encode(Bin, jsonb, _) ->
|
|
encode(Bin, jsonb, _) ->
|
|
[<<?JSONB_VERSION_1:8>> | Bin].
|
|
[<<?JSONB_VERSION_1:8>> | Bin].
|
|
|
|
|
|
|
|
+decode(Bin, json, JsonMod) when is_atom(JsonMod) ->
|
|
|
|
+ JsonMod:decode(Bin);
|
|
|
|
+decode(Bin, json, {JsonMod, _, {decode, Opts}}) when is_atom(JsonMod) ->
|
|
|
|
+ JsonMod:decode(Bin, Opts);
|
|
|
|
+decode(<<?JSONB_VERSION_1:8, Bin/binary>>, jsonb, JsonMod) when is_atom(JsonMod) ->
|
|
|
|
+ JsonMod:decode(Bin);
|
|
|
|
+decode(<<?JSONB_VERSION_1:8, Bin/binary>>, jsonb, {JsonMod, _, {decode, Opts}}) when is_atom(JsonMod) ->
|
|
|
|
+ JsonMod:decode(Bin, Opts);
|
|
decode(Bin, json, _) ->
|
|
decode(Bin, json, _) ->
|
|
Bin;
|
|
Bin;
|
|
decode(<<?JSONB_VERSION_1:8, Bin/binary>>, jsonb, _) ->
|
|
decode(<<?JSONB_VERSION_1:8, Bin/binary>>, jsonb, _) ->
|