emqx_json.erl 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. -module(emqx_json).
  17. -compile(inline).
  18. -export([ encode/1
  19. , encode/2
  20. , safe_encode/1
  21. , safe_encode/2
  22. ]).
  23. -compile({inline,
  24. [ encode/1
  25. , encode/2
  26. ]}).
  27. -export([ decode/1
  28. , decode/2
  29. , safe_decode/1
  30. , safe_decode/2
  31. ]).
  32. -compile({inline,
  33. [ decode/1
  34. , decode/2
  35. ]}).
  36. -type(encode_options() :: jiffy:encode_options()).
  37. -type(decode_options() :: jiffy:decode_options()).
  38. -type(json_text() :: iolist() | binary()).
  39. -type(json_term() :: jiffy:jiffy_decode_result()).
  40. -export_type([json_text/0, json_term/0]).
  41. -export_type([decode_options/0, encode_options/0]).
  42. -spec(encode(json_term()) -> json_text()).
  43. encode(Term) ->
  44. encode(Term, [force_utf8]).
  45. -spec(encode(json_term(), encode_options()) -> json_text()).
  46. encode(Term, Opts) ->
  47. to_binary(jiffy:encode(to_ejson(Term), Opts)).
  48. -spec(safe_encode(json_term())
  49. -> {ok, json_text()} | {error, Reason :: term()}).
  50. safe_encode(Term) ->
  51. safe_encode(Term, [force_utf8]).
  52. -spec(safe_encode(json_term(), encode_options())
  53. -> {ok, json_text()} | {error, Reason :: term()}).
  54. safe_encode(Term, Opts) ->
  55. try encode(Term, Opts) of
  56. Json -> {ok, Json}
  57. catch
  58. error:Reason ->
  59. {error, Reason}
  60. end.
  61. -spec(decode(json_text()) -> json_term()).
  62. decode(Json) -> decode(Json, []).
  63. -spec(decode(json_text(), decode_options()) -> json_term()).
  64. decode(Json, Opts) ->
  65. from_ejson(jiffy:decode(Json, Opts)).
  66. -spec(safe_decode(json_text())
  67. -> {ok, json_term()} | {error, Reason :: term()}).
  68. safe_decode(Json) ->
  69. safe_decode(Json, []).
  70. -spec(safe_decode(json_text(), decode_options())
  71. -> {ok, json_term()} | {error, Reason :: term()}).
  72. safe_decode(Json, Opts) ->
  73. try decode(Json, Opts) of
  74. Term -> {ok, Term}
  75. catch
  76. error:Reason ->
  77. {error, Reason}
  78. end.
  79. %%--------------------------------------------------------------------
  80. %% Helpers
  81. %%--------------------------------------------------------------------
  82. -compile({inline,
  83. [ to_ejson/1
  84. , from_ejson/1
  85. ]}).
  86. to_ejson([{}]) ->
  87. {[]};
  88. to_ejson([{_, _}|_] = L) ->
  89. {[{K, to_ejson(V)} || {K, V} <- L ]};
  90. to_ejson(L) when is_list(L) ->
  91. [to_ejson(E) || E <- L];
  92. to_ejson(T) -> T.
  93. from_ejson(L) when is_list(L) ->
  94. [from_ejson(E) || E <- L];
  95. from_ejson({[]}) ->
  96. [{}];
  97. from_ejson({L}) ->
  98. [{Name, from_ejson(Value)} || {Name, Value} <- L];
  99. from_ejson(T) -> T.
  100. to_binary(B) when is_binary(B) -> B;
  101. to_binary(L) when is_list(L) ->
  102. iolist_to_binary(L).