jsx icon indicating copy to clipboard operation
jsx copied to clipboard

why record can not encode and decode by jsx

Open lcwxz1989 opened this issue 7 years ago • 3 comments

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)

lcwxz1989 avatar Aug 16 '16 08:08 lcwxz1989

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).

talentdeficit avatar Aug 17 '16 01:08 talentdeficit

@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.

okeuday avatar Aug 17 '16 07:08 okeuday

Is this an actual issue? Back in 2016, probably, but now with all the map support and so...

paulo-ferraz-oliveira avatar Sep 12 '20 01:09 paulo-ferraz-oliveira