Open4

Erlang/OTP 27.0 で入る予定の json モジュールのメモ

voluntasvoluntas

OTP 27.0 で json モジュールを入れようという流れが来ています。Erlang/OTP には今まで json モジュールを提供しておりませんでした。

json モジュールを提案しているのは WhatsApp の人で、 Elixir の jason の開発者です。
https://github.com/michalmuskala/jason

機能はシンプルで json:encode/1json:decode/1 が基本的な機能です。

encode

> json:encode(#{spam => #{egg => 10}}).
["{",
 [[34,<<"spam">>,34],
  58,"{",
  [[34,<<"egg">>,34],58|<<"10">>],
  [],"}"],
 [],"}"]

iodata() で戻ってきます。

decode

> json:decode(<<"null">>).
null

json:value() として戻ってきます。

-type value() ::
    integer() |
    float() |
    boolean() |
    null |
    binary() |
    list(value()) |
    #{binary() => value()}.
voluntasvoluntas

json:encoder/2

エンコードはカスタムエンコーダーを定義できるので、既存で利用している json ライブラリからの切り替えもしやすくなっています。

undefined が入っている場合その key を含まなくするカスタムエンコーダーの例

1> Encoder = fun (Map, Encode) when is_map(Map) ->
           json:encode_key_value_list([{Key, Value} || Key := Value <- Map, Value =/= undefined], Encode);
       (Other, Encode) ->
           json:encode_value(Other, Encode)
   end.
#Fun<erl_eval.41.39164016>
2> iolist_to_binary(json:encode(#{a => undefined, b => c}, Encoder)).
<<"{\"b\":\"c\"}">>

https://github.com/erlang/eep/pull/59#discussion_r1486151251

voluntasvoluntas

フォーマッターとプリティプリント

json:format/1 が用意されます。ただまだ未実装です。

-type format_option() :: #{
    indent => iodata(),
    line_separator => iodata(),
    after_colon => iodata()
}.
-spec format(iodata()) -> iodata().
-spec format(iodata(), format_option()) -> iodata().
voluntasvoluntas

jsone ユーザー

基本的に標準モジュールを使いたいや、速度が速いなどがない限りは jsone のままで良いと思う。

jsone が実装している key を atom にしてデコードしたり、map の value が undefined の時は skips するといった機能がない。