Initial commit
This commit is contained in:
22
lib/translator/base.ex
Normal file
22
lib/translator/base.ex
Normal file
@@ -0,0 +1,22 @@
|
||||
defmodule Localizator.Translator.Base do
|
||||
@typedoc """
|
||||
Plain Text
|
||||
"""
|
||||
@type text :: String.t()
|
||||
|
||||
@typedoc """
|
||||
Locale
|
||||
"""
|
||||
@type locale :: String.t()
|
||||
@type from :: locale
|
||||
@type to :: locale
|
||||
|
||||
@typedoc """
|
||||
Error Message
|
||||
"""
|
||||
@type message :: String.t()
|
||||
|
||||
@callback detect(text) :: {:ok, locale} | {:error, message}
|
||||
@callback translate(text, to) :: {:ok, text} | {:error, message}
|
||||
@callback translate(text, to, from) :: {:ok, text} | {:error, message}
|
||||
end
|
||||
31
lib/translator/direction/direction.ex
Normal file
31
lib/translator/direction/direction.ex
Normal file
@@ -0,0 +1,31 @@
|
||||
defmodule Localizator.Translator.Direction do
|
||||
alias Localizator.Commons
|
||||
|
||||
defstruct [:from, :to]
|
||||
|
||||
@typedoc """
|
||||
Locale
|
||||
"""
|
||||
@type locale :: String.t() | Atom.t()
|
||||
@type from :: locale
|
||||
@type from_may_be_nil :: from | nil
|
||||
@type to :: locale
|
||||
@type direction :: {from, to} | to | %{from: from, to: to} | %{to: to}
|
||||
@type direction_struct :: %{to: to, from: from_may_be_nil}
|
||||
|
||||
@spec get(direction) :: direction_struct
|
||||
def get(direction) do
|
||||
direction_map =
|
||||
case direction do
|
||||
[from: from, to: to] -> %{to: "#{to}", from: "#{from}"}
|
||||
[from, to] -> %{to: "#{to}", from: "#{from}"}
|
||||
{from, to} -> %{to: "#{to}", from: "#{from}"}
|
||||
%{from: from, to: to} -> %{to: "#{to}", from: "#{from}"}
|
||||
%{to: to} -> %{to: "#{to}", from: nil}
|
||||
[to: to] -> %{to: "#{to}", from: nil}
|
||||
to -> %{to: "#{to}", from: nil}
|
||||
end
|
||||
|
||||
Commons.struct_from_map(direction_map, as: %__MODULE__{})
|
||||
end
|
||||
end
|
||||
47
lib/translator/translator.ex
Normal file
47
lib/translator/translator.ex
Normal file
@@ -0,0 +1,47 @@
|
||||
defmodule Localizator.Translator do
|
||||
alias Localizator.Translator.Direction
|
||||
|
||||
@typedoc """
|
||||
Locale
|
||||
"""
|
||||
@type locale :: String.t()
|
||||
@type from :: locale
|
||||
@type from_may_be_nil :: from | nil
|
||||
@type to :: locale
|
||||
@type direction :: {from, to} | to | %{from: from, to: to} | %{to: to}
|
||||
@type direction_map :: %{to: to, from: from_may_be_nil}
|
||||
|
||||
@typedoc """
|
||||
Translation service
|
||||
"""
|
||||
@type translator :: Atom.t()
|
||||
|
||||
@typedoc """
|
||||
Translation services list
|
||||
"""
|
||||
@type translators :: [translator]
|
||||
|
||||
@typedoc """
|
||||
Translation resource
|
||||
"""
|
||||
@type resource :: String.t() | Map.t() | List.t()
|
||||
@type source :: resource
|
||||
@type result :: resource
|
||||
|
||||
@typedoc """
|
||||
Error Message
|
||||
"""
|
||||
@type message :: String.t()
|
||||
|
||||
@spec list() :: translators
|
||||
def list(), do: Application.get_env(:localizator, :translators)
|
||||
|
||||
@spec default() :: translator
|
||||
def default(), do: list() |> List.first()
|
||||
|
||||
@spec translate(source, direction, translator) :: {:ok, result} | {:error, message}
|
||||
def translate(source, direction, translator \\ default()) do
|
||||
map = Direction.get(direction)
|
||||
translator.translate(source, map.to, map.from)
|
||||
end
|
||||
end
|
||||
40
lib/translator/yandex.ex
Normal file
40
lib/translator/yandex.ex
Normal file
@@ -0,0 +1,40 @@
|
||||
defmodule Localizator.Translator.Yandex do
|
||||
@type text :: String.t()
|
||||
@type locale :: String.t()
|
||||
@type from :: locale
|
||||
@type to :: locale
|
||||
@type message :: String.t()
|
||||
|
||||
@behaviour Localizator.Translator.Base
|
||||
|
||||
@impl true
|
||||
@spec detect(text) :: {:ok, locale} | {:error, message}
|
||||
def detect(text) when is_bitstring(text) do
|
||||
case YandexTranslate.detect(text) do
|
||||
%{languageCode: locale} -> {:ok, locale}
|
||||
%{} -> {:error, "Couldn't detect language"}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
@spec translate(text, to) :: {:ok, text} | {:error, message}
|
||||
def translate(text, to, from \\ nil)
|
||||
|
||||
def translate(text, to, from) when is_bitstring(text) and is_bitstring(to) do
|
||||
translator_response =
|
||||
case from do
|
||||
nil -> YandexTranslate.translate(text, to)
|
||||
_ -> YandexTranslate.translate(text, to, from)
|
||||
end
|
||||
|
||||
case translator_response do
|
||||
%{translations: translations} ->
|
||||
translations
|
||||
|> List.first()
|
||||
|> Map.fetch(:text)
|
||||
|
||||
%{message: message} ->
|
||||
{:error, message}
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user