Skip to content

Commit

Permalink
edoc generation
Browse files Browse the repository at this point in the history
  • Loading branch information
44044 committed May 29, 2019
1 parent 8ab0243 commit 8b158cb
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 25 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
*.beam
*.crashdump
_build/
doc/*
!doc/overview.edoc
src/fieldmask_lexer.erl
src/fieldmask_parser.erl
rebar.lock
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ before_install:
script:
- rebar3 ct --readable=false
- rebar3 compile
- rebar3 edoc
after_success:
- rebar3 as test coveralls send
deploy:
Expand Down
27 changes: 27 additions & 0 deletions doc/overview.edoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@title fieldmask
@doc fieldmask implements Google Partial Response Protocol in Erlang.

Mask of fieldmask is the same as `fields' parameter of Google+ API, for example, `<<"a,b">>' means the fields you want to keep is `"a"' and `"b"'.

```
1> Mask = <<"a,b">>.
<<"a,b">>
'''

And fieldmask use map object format of <a href="https://github.com/sile/jsone">jsone</a> to represent a JSON value.

```
2> Value = jsone:decode(<<"{\"a\":1, \"b\": 2, \"c\": 3}">>).
#{<<"a">> => 1,<<"b">> => 2,<<"c">> => 3}.
'''

Call `fieldmask:mask/2' to get the specific parts of a value you've selected.

```
3> fieldmask:mask(Mask, Value).
#{<<"a">> => 1,<<"b">> => 2}
'''

@reference Google+ API <a href="https://developers.google.com/+/web/api/rest/#partial-response">Partial Responses</a>
@reference NPM package <a href="https://www.npmjs.com/package/json-mask">json-mask</a>
@reference PyPI package <a href="https://pypi.org/project/jsonmask/">jsonmask</a>
2 changes: 1 addition & 1 deletion hex.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

set -e

rebar3 do hex config username "$1", hex config key "$2", hex publish <<EOF
rebar3 do hex config username "$1", hex config key "$2", hex publish, hex docs <<EOF
y
EOF
1 change: 1 addition & 0 deletions rebar.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{erl_opts, [debug_info]}.
{deps, []}.
{provider_hooks, [{pre, [{edoc, {default, clean}}]}]}.
{cover_enabled, true}.
{cover_export_enabled, true}.
{cover_excl_mods, [fieldmask_lexer, fieldmask_parser]}.
Expand Down
2 changes: 1 addition & 1 deletion src/fieldmask.app.src
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{application, fieldmask,
[
{description, "Implements Google Partial Response/json-mask in Erlang."},
{description, "Implements Google Partial Response protocol in Erlang."},
{vsn, "git"},
{modules, []},
{registered, []},
Expand Down
58 changes: 45 additions & 13 deletions src/fieldmask.erl
Original file line number Diff line number Diff line change
@@ -1,31 +1,63 @@
-module(fieldmask).

-export([parse/1, mask/2]).
-export([mask/2, parse/1, apply_mask/2]).

parse(S) ->
case fieldmask_lexer:string(S) of
-type value() :: null
| number()
| boolean()
| binary()
| [value()]
| #{binary() => value()}.
%% type of a JSON value represented in jsone's map object format.

-type mask_expr() :: string() | binary().
%% type of mask expression. You may use a string or a binary as mask expression.

-type mask() :: '*'
| {'*', mask()}
| [submask()].

-type submask() :: binary()
| {binary(), mask()}.

%% @doc select the parts specified in the `Mask' expression of a `Value'
-spec mask(mask_expr(), value()) -> value().
mask(Mask, Value) ->
{ok, M} = parse(Mask),
apply_mask(M, Value).

%% @doc parse the `Mask' expression to internal representation
-spec parse(mask_expr()) -> Result
when Result :: {ok, mask()} | Error,
Error :: {error, {Line, module(), Reason}},
Line :: pos_integer(),
Reason :: term().
parse(Mask) ->
case fieldmask_lexer:string(unicode:characters_to_list(Mask)) of
{ok, Tokens, _} ->
fieldmask_parser:parse(Tokens);
{error, Error, _} ->
{error, Error}
end.

mask(Mask, Value) when is_list(Value) ->
[mask(Mask, E) || E <- Value];
mask('*', Value) ->
%% @doc apply `Mask' in internal representation to a `Value'
-spec apply_mask(mask(), value()) -> value().
apply_mask(Mask, Value) when is_list(Value) ->
[apply_mask(Mask, E) || E <- Value];
apply_mask('*', Value) ->
Value;
mask({'*', Submask}, Value) ->
maps:map(fun(_, V) -> mask(Submask, V) end, Value);
mask({Key, Submask}, Value) when is_binary(Key) ->
mask(Submask, mask(Key, Value));
mask(Mask, Value) when is_list(Mask)->
apply_mask({'*', Submask}, Value) ->
maps:map(fun(_, V) -> apply_mask(Submask, V) end, Value);
apply_mask({Key, Submask}, Value) when is_binary(Key) ->
apply_mask(Submask, apply_mask(Key, Value));
apply_mask(Mask, Value) when is_list(Mask)->
maps:from_list(
[{case E of
{Key, _} ->
Key;
_ ->
E
end,
mask(E, Value)}|| E <- Mask]);
mask(Key, Value) when is_binary(Key) ->
apply_mask(E, Value)}|| E <- Mask]);
apply_mask(Key, Value) when is_binary(Key) ->
maps:get(Key, Value).
16 changes: 6 additions & 10 deletions test/fieldmask_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,19 @@ test_mask(_Config) ->
]
},

Data = fieldmask:mask('*', Data),
Data = fieldmask:mask("*", Data),

%% fields=kind
Part1 = #{<<"kind">> => <<"demo">>},
Part1 = fieldmask:mask([<<"kind">>], Data),
Part1 = fieldmask:mask("kind", Data),

%% fields=kind,items/title
Part2 =
#{<<"kind">> => <<"demo">>,
<<"items">> =>
[
#{<<"title">> => <<"First title">>},
#{<<"title">> => <<"Second title">>}
]},
Part2 = fieldmask:mask([<<"kind">>, {<<"items">>, [<<"title">>]}], Data),
Part2 = fieldmask:mask("kind,items/title", Data),

Part3 =
#{<<"kind">> => <<"demo">>,
Expand All @@ -63,7 +61,7 @@ test_mask(_Config) ->
#{<<"title">> => <<"Second title">>,
<<"status">> => <<"pending">>}
]},
Part3 = fieldmask:mask([<<"kind">>, {<<"items">>, [<<"title">>, <<"status">>]}], Data),
Part3 = fieldmask:mask("kind,items(title,status)", Data),

Part4 =
#{<<"items">> =>
Expand All @@ -88,8 +86,7 @@ test_mask(_Config) ->
]
},

%% items/pagemap/*
Part4 = fieldmask:mask([{<<"items">>, [{<<"pagemap">>, '*'}]}], Data),
Part4 = fieldmask:mask("items/pagemap/*", Data),

Part5 =
#{<<"items">> =>
Expand All @@ -113,8 +110,7 @@ test_mask(_Config) ->
]
},

%% items/pagemap/*/title
Part5 = fieldmask:mask([{<<"items">>, [{<<"pagemap">>, {'*', [<<"title">>]}}]}], Data),
Part5 = fieldmask:mask("items/pagemap/*/title", Data),
ok.

test_lex_error(_Config) ->
Expand Down

0 comments on commit 8b158cb

Please sign in to comment.