/src/jsonerl.hrl

http://github.com/lambder/jsonerl · Erlang · 72 lines · 56 code · 4 blank · 12 comment · 1 complexity · f1f23ac649e60f716a4b36ce3ccf50db MD5 · raw file

  1. -define(record_to_struct(RecordName, Record),
  2. % we are zipping record's field names and corresponding values together
  3. % then we turn it into tuple resulting in *struct* - erlang's equivalent of json's *object*
  4. list_to_tuple(
  5. lists:zip(
  6. lists:map(fun(F) -> list_to_binary(atom_to_list(F)) end, record_info(fields, RecordName)),
  7. lists:map(
  8. %% convention record's *undefined* value is represented as json's *null*
  9. fun(undefined) -> null;
  10. (E) -> E
  11. end,
  12. %% we are turning the record into list chopping its head (record name) off
  13. tl(tuple_to_list(Record))
  14. )
  15. )
  16. )
  17. ).
  18. -define(struct_to_record(RecordName, Struct),
  19. % I use fun here in order to avoid possible variable collison by shaddowing them
  20. fun(ValuesByFieldsDict) ->
  21. % construct the tuple being the proper record from the struct
  22. list_to_tuple(
  23. %% first element in the tuple is record name
  24. [RecordName] ++
  25. lists:map(
  26. %% convention: json's *null* represents record's *undefined* value
  27. fun(Field) ->
  28. case dict:find(Field, ValuesByFieldsDict) of
  29. {ok, Value} -> Value;
  30. error -> undefined
  31. end
  32. end,
  33. % getting the record field names in the order the tuple representing the record instance has its values
  34. record_info(fields, RecordName)
  35. )
  36. )
  37. end(
  38. % create quickly accessible maping of struct values by its keys turned to atoms, as it is in records.
  39. lists:foldl(
  40. fun({K, V}, Dict) ->
  41. dict:store(jsonerl:to_ex_a(K), V, Dict)
  42. end,
  43. dict:new(),
  44. tuple_to_list(Struct)
  45. )
  46. )
  47. ).
  48. -define(record_to_json(RecordName, Record),
  49. % serialize erlang struct into json string
  50. jsonerl:encode(?record_to_struct(RecordName, Record))
  51. ).
  52. -define(list_records_to_json(RecordName, List),
  53. L___ = length(List),
  54. Zipped___ = lists:zip(lists:seq(1,L___),List),
  55. Quotes___ = lists:map(
  56. fun({N___,X___}) ->
  57. case L___ == N___ of
  58. false ->
  59. Json___ = jsonerl:encode(?record_to_struct(RecordName,X___)),
  60. Json___ ++ ",";
  61. true -> jsonerl:encode(?record_to_struct(RecordName,X___))
  62. end
  63. end, Zipped___),
  64. lists:flatten(io_lib:format("~s",["["++Quotes___++"]"]))).
  65. -define(json_to_record(RecordName, Json),
  66. % decode json text to erlang struct
  67. ?struct_to_record(RecordName, jsonerl:decode(Json))
  68. ).