Current section
Files
Jump to
Current section
Files
src/deeperl_translate.erl
%%% @private
-module(deeperl_translate).
-behavior(gen_deeperl_procedure).
%% API
-export([uri/0, body/1, response/1]).
-export_type([result/0]).
-type result() :: [{DetectedSourceLanguage :: deeperl:language(), Text :: binary()}] | {error, invalid_response} | {error, {bad_option, Option :: any()}}.
uri() ->
"/v2/translate".
-spec body({TargetLang :: deeperl:language(), Texts :: [iodata()], Options :: deeperl:translation_options()}) -> iodata().
body({TargetLang, [T|_] = Texts, Options}) when is_list(T) ->
case format_translate_options(maps:to_list(Options), []) of
{error, _} = E -> E;
O ->
[
[["&text=", http_uri:encode(Text)] || Text <- Texts],
[["&", K, "=", V] || {K, V} <- O],
"&target_lang=", http_uri:encode(string:uppercase(atom_to_list(TargetLang)))
]
end;
body({_, _, _}) ->
{error, bad_text_format}.
-spec response(Data :: map()) -> deeperl:translate_result().
response(#{<<"translations">> := Translations}) ->
response(Translations, []);
response(_) ->
{error, invalid_response}.
%% internal
-spec response(Data :: map(), Acc :: deeperl:translate_result()) -> deeperl:translate_result().
response([#{<<"detected_source_language">> := Language, <<"text">> := Text}|Rest], Acc) ->
Item = {list_to_atom(string:lowercase(unicode:characters_to_list(Language))), iolist_to_binary(Text)},
response(Rest, [Item|Acc]);
response([], Acc) ->
lists:reverse(Acc);
response(_, _) ->
{error, invalid_response}.
format_translate_options([Option|Options], Acc) ->
case format_translate_option(Option) of
{error, _Reason} = E -> E;
O -> format_translate_options(Options, [O|Acc])
end;
format_translate_options([], Acc) ->
Acc.
format_translate_option({source_lang, Value}) ->
{"source_lang", string:uppercase(atom_to_list(Value))};
format_translate_option({split_sentences, Value}) when is_boolean(Value); Value == nonewlines ->
{"split_sentences", case Value of
true -> "1";
false -> "0";
nonewlines -> "nonewlines"
end};
format_translate_option({preserve_formatting, Value}) when is_boolean(Value) ->
{"preserve_formatting", case Value of
true -> "1";
false -> "0"
end};
format_translate_option({tag_handling, xml}) ->
{"tag_handling", "xml"};
format_translate_option({outline_detection, Value}) when is_boolean(Value) ->
{"outline_detection", case Value of
true -> "1";
false -> "0"
end};
format_translate_option({non_splitting_tags, Value}) when is_list(Value) ->
{"non_splitting_tags", string:join(lists:map(fun http_uri:encode/1, Value), ",")};
format_translate_option({splitting_tags, Value}) when is_list(Value) ->
{"splitting_tags", string:join(lists:map(fun http_uri:encode/1, Value), ",")};
format_translate_option({ignore_tags, Value}) when is_list(Value) ->
{"ignore_tags", string:join(lists:map(fun http_uri:encode/1, Value), ",")};
format_translate_option(Option) ->
{error, {bad_option, Option}}.