Current section

Files

Jump to
accept src accept_parser.erl
Raw

src/accept_parser.erl

%% @private
-module(accept_parser).
-export([ensure_string/1,
parse/1,
parse_option/1,
map_options/2]).
-include("accept.hrl").
%%====================================================================
%% Public API
%%====================================================================
ensure_string(V) when is_list(V) ->
V;
ensure_string(V) when is_binary(V) ->
binary_to_list(V).
map_options(_, "") ->
[];
map_options(_, <<"">>) ->
[];
map_options(Fun, String) ->
lists:filtermap(fun (OptionStr) ->
case parse_option(OptionStr) of
false -> false;
Option -> {true, Fun(Option)}
end
end,
string:tokens(ensure_string(String), ",")).
parse(String) ->
map_options(fun (A) -> A end, String).
parse_option(OptionStr) ->
[Option | RawParams] = lists:map(fun string:strip/1,
string:tokens(OptionStr, ";")),
case Option of
"" ->
false; %% ignore malformed option
_ ->
Params = lists:filtermap(fun parse_param/1, RawParams),
{Q, ParamsWOQ} = find_q(Params),
#accept_option{option=Option,
q=Q,
params=ParamsWOQ}
end.
%%====================================================================
%% Private Parts
%%====================================================================
parse_param(Param) ->
case string:tokens(Param, "=") of
[Name, Value] -> {true, {Name, Value}};
_ -> false %% simply ignore malformed Name=Value pairs
end.
find_q(Params) ->
{parse_q(proplists:get_value("q", Params, "1")),
proplists:delete("q", Params)}.
parse_q(Q) ->
%% extremely relaxed parser
try
case lists:member($., Q) of
true ->
list_to_float(Q);
false ->
list_to_integer(Q)
end
catch error:badarg ->
0
end.