Open lcwxz1989 opened 8 years ago
there's no reasonable way for jsx to get a record's fields at runtime, so the best possible encoding would probably be just a list of the values. that wouldn't allow decoding to a record though
you can write your own encoder that supports records though:
-module(recordizer).
-export([encode/1]).
%% custom encoder callback
-export([encode/2]).
-record(message1, {
expire,
num
}).
%% the parser is unmodified but the term passed to the parser instance is
%% preencoded by the custom `encode/2` function below
encode(Term) ->
(jsx:parser(jsx_to_json, [], [escaped_strings]))(encode(Term, ?MODULE) ++ [end_json]).
%% this captures any instance that matches the record as a top level term, the value
%% for a map or proplist entry or a member of a list and returns a map to the parser
%% instead. anything else is handled by the default parser in `jsx_encoder`
encode(Message, _EntryPoint) when is_record(Message, message1) ->
[#{expire => Message#message1.expire, num => Message#message1.num}];
encode(Term, EntryPoint) ->
jsx_encoder:encode(Term, EntryPoint).
@lcwxz1989 records only exist during preprocessing, so if you want them to automatically go to/from json with jsx, you will need a parse transform. I have one at https://github.com/okeuday/record_info_runtime/ which can provide the record field names based on the record name with the function record_info_fields/1
. With that, you can make code automatically go to/from json.
However, the reason to not make it automatic is to have better type checking on the record types. That approach argues for manually creating the json based on the record fields and not using a parse transform.
Is this an actual issue? Back in 2016, probably, but now with all the map support and so...
I have a record type need to encode and decode, but I find jsx did not support demo (push@demo)1> rd(message1, {expire, num}). message1 (push@demo)2> jsx:encode(#{a => #message1{expire=1,num=2}}). \ exception error: bad argument in function jsx_parser:value/4 (src/jsx_parser.erl, line 129)