Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add Erlang library to parse Erlang configs to JSON

  • Loading branch information...
commit 62d93e38048ab6b84283f73980d14fedf37631e1 1 parent cc6569a
Daniel Reverri dreverri authored
3  .gitignore
View
@@ -16,3 +16,6 @@ test/tmp
test/version_tmp
tmp
.DS_Store
+.eunit
+erl_src/deps
+erl_src/ebin
30 erl_src/Makefile
View
@@ -0,0 +1,30 @@
+REBAR := rebar
+
+.PHONY: deps test
+
+all: deps compile
+
+deps:
+ $(REBAR) get-deps
+
+compile: deps
+ $(REBAR) compile
+
+clean:
+ $(REBAR) clean
+
+distclean: clean
+ $(REBAR) delete-deps
+
+test: compile
+ifdef suite
+ $(REBAR) skip_deps=true eunit suite=$(suite)
+else
+ $(REBAR) skip_deps=true eunit
+endif
+
+console: compile
+ erl -pa ebin deps/*/ebin
+
+escript: compile
+ $(REBAR) skip_deps=true escriptize
6 erl_src/rebar.config
View
@@ -0,0 +1,6 @@
+{deps, [
+ {jsx, "1.3.1",
+ {git, "git://github.com/talentdeficit/jsx.git", {tag, "v1.3.1"}}}
+ ]}.
+
+{escript_incl_apps, [jsx]}.
11 erl_src/src/eth.app.src
View
@@ -0,0 +1,11 @@
+{application, eth,
+ [
+ {description, ""},
+ {vsn, "1"},
+ {registered, []},
+ {applications, [
+ kernel,
+ stdlib
+ ]},
+ {env, []}
+ ]}.
74 erl_src/src/eth.erl
View
@@ -0,0 +1,74 @@
+-module(eth).
+
+-export([convert/1]).
+
+-export([is_convertible_proplist/1, is_string/1]).
+
+convert(Term) ->
+ if
+ is_atom(Term) -> convert_atom(Term);
+ is_binary(Term) -> convert_binary(Term);
+ is_list(Term) -> convert_list(Term);
+ is_tuple(Term) -> convert_tuple(Term);
+ is_number(Term) -> Term;
+ true -> throw({unrecognized_term, Term})
+ end.
+
+convert_atom(Atom) when Atom =:= true; Atom =:= false; Atom =:= null ->
+ Atom;
+
+convert_atom(Atom) ->
+ case is_reserved_atom(Atom) of
+ true -> <<"__atom_", (atom_to_binary(Atom, utf8))/binary>>;
+ false -> atom_to_binary(Atom, utf8)
+ end.
+
+convert_binary(Binary) ->
+ <<"__binary_", Binary/binary>>.
+
+convert_string(String) ->
+ <<"__string_", (list_to_binary(String))/binary>>.
+
+convert_list(List) ->
+ case is_string(List) of
+ true -> convert_string(List);
+ false ->
+ case is_convertible_proplist(List) of
+ true -> convert_proplist(List);
+ false -> [convert(Term) || Term <- List]
+ end
+ end.
+
+convert_tuple(Tuple) ->
+ [<<"__tuple">>|[convert(Term) || Term <- tuple_to_list(Tuple)]].
+
+convert_proplist(Proplist) ->
+ [{convert(Key), convert(Value)} || {Key, Value} <- Proplist].
+
+%% key must be atom, string, or binary
+is_convertible_proplist(List) ->
+ lists:all(fun is_2tuple/1, List).
+
+is_2tuple({Key,_}) ->
+ if
+ is_atom(Key) -> true;
+ is_binary(Key) -> true;
+ true -> is_string(Key)
+ end;
+
+is_2tuple(_) ->
+ false.
+
+is_string(List) ->
+ io_lib:printable_list(List).
+
+%% reserved atoms are used to encode lists, tuples, atomss, binaries, and strings
+%% a reserved atom is one that is prefixed with '__'
+is_reserved_atom(Atom) when is_atom(Atom) ->
+ case atom_to_list(Atom) of
+ "__" ++ _ -> true;
+ _ -> false
+ end;
+
+is_reserved_atom(_) ->
+ false.
43 erl_src/test/eth_test.erl
View
@@ -0,0 +1,43 @@
+-module(eth_test).
+
+-include_lib("eunit/include/eunit.hrl").
+
+%% convert Erlang terms to an intermediate Erlang structure which can be encoded
+%% as JSON by https://github.com/talentdeficit/jsx
+convert_atom_test() ->
+ <<"key">> = eth:convert(key),
+ <<"__atom___binary_key">> = eth:convert('__binary_key'),
+ <<"__atom___string_key">> = eth:convert('__string_key').
+
+convert_binary_test() ->
+ <<"__binary_key">> = eth:convert(<<"key">>).
+
+convert_string_test() ->
+ <<"__string_key">> = eth:convert("key").
+
+convert_list_test() ->
+ ?assertEqual([1, 2, 3], eth:convert([1, 2, 3])),
+ ?assertEqual([<<"__atom___list">>, 1, 2, 3], eth:convert(['__list', 1, 2, 3])),
+ ?assertEqual([<<"__atom___tuple">>, 1, 2, 3], eth:convert(['__tuple', 1, 2, 3])).
+
+convert_tuple_test() ->
+ ?assertEqual([<<"__tuple">>, 1, 2, 3], eth:convert({1, 2, 3})),
+ ?assertEqual([<<"__tuple">>, <<"__atom___list">>, 1, 2, 3], eth:convert({'__list', 1, 2, 3})),
+ ?assertEqual([<<"__tuple">>, <<"__atom___tuple">>, 1, 2, 3], eth:convert({'__tuple', 1, 2, 3})).
+
+convert_proplist_test() ->
+ [{<<"storage_backend">>, <<"bitcask">>}] = eth:convert([{storage_backend, bitcask}]).
+
+convert_boolean_test() ->
+ true = eth:convert(true),
+ false = eth:convert(false).
+
+convert_null_test() ->
+ null = eth:convert(null).
+
+comparison_test() ->
+ {ok, Binary} = file:read_file("../../test/examples/multi_backend.json"),
+ {ok, [Terms]} = file:consult("../../test/examples/multi_backend.config"),
+ Json = jsx:decode(Binary),
+ Config = eth:convert(Terms),
+ ?assertEqual(Json, Config).
Please sign in to comment.
Something went wrong with that request. Please try again.