Packages

Generates a phonetically pronounced token with given mask or default mask "CVCCV-CVCVV-DDDDD"

Current section

Files

Jump to
phonex lib phonex.ex
Raw

lib/phonex.ex

defmodule Phonex do
@default_mask Application.compile_env!(:phonex, :default_mask)
@consts "bcdgklmnprstz"
@vowels "aeiou"
@blocklist Application.compile_env!(:phonex, :blocklist)
@moduledoc ~S"""
Generates a phonetically pronounced token with givn mask (or default mask)
Mask configuration:
- `C` — consoinant character
- `V` — vowel character
- `D` — digit
- `other` — any other symbol
Mask should be ASCII symbols
"""
@doc """
Generates a token with default mask `"CVCCV-CVCVV-DDDDD"`
## Examples
iex> Phonex.token()
{:ok, "kobsa-mitau-52876"}
iex(4)> Phonex.token(nil)
{:error, "Mask cannot be nil. Possible format CVCCV-CVCVV-DDDDD"}
"""
def token do
String.graphemes(@default_mask)
|> token_by_mask()
|> check_token()
end
@doc ~S"""
Generates a token with default mask `"CVCCV-CVCVV-DDDDD"`
## Examples
iex> Phonex.token!()
{:ok, "kobsa-mitau-52876"}
"""
def token! do
String.graphemes(@default_mask)
|> token_by_mask()
|> check_token!()
end
@doc """
Generates a token with given mask
## Examples
iex> Phonex.token("CVCCV-CVCVV-DDDDD")
{:ok, "kobsa-mitau-52876"}
"""
def token(mask) do
check_mask(mask)
|> graphemes()
|> token_by_mask()
|> check_token()
end
@doc ~S"""
Generates a token with given mask
## Examples
iex> Phonex.token!("CVCCV-CVCVV-DDDDD")
{:ok, "kobsa-mitau-52876"}
iex(4)> Phonex.token!(nil)
** (ArgumentError) Mask cannot be nil. Possible format CVCCV-CVCVV-DDDDD
(phonex 0.1.0) lib/phonex.ex:92: Phonex.check_mask!/1
(phonex 0.1.0) lib/phonex.ex:76: Phonex.token!/1
iex:4: (file)
"""
def token!(mask) do
check_mask!(mask)
|> graphemes()
|> token_by_mask()
|> check_token!()
end
defp check_mask(mask) do
cond do
is_nil(mask) == true -> {:error, "Mask cannot be nil. Possible format #{@default_mask}"}
String.match?(mask, ~r/\A[\x00-\x7F]+\z/) == false -> {:error, "Mask must be an ASCII string. Possible format #{@default_mask}"}
true -> mask
end
end
defp check_mask!(mask) do
cond do
is_nil(mask) == true -> raise ArgumentError, "Mask cannot be nil. Possible format #{@default_mask}"
String.match?(mask, ~r/\A[\x00-\x7F]+\z/) == false -> raise ArgumentError, "Mask must be an ASCII string. Possible format #{@default_mask}"
true -> mask
end
end
defp graphemes({:error, _} = e), do: e
defp graphemes(mask), do: String.graphemes(mask)
defp token_by_mask({:error, _} = e), do: e
defp token_by_mask(mask_list) do
mask_list
|> Enum.map(fn
"C" -> Enum.random(String.graphemes(@consts))
"D" -> Enum.random(String.graphemes("0123456789"))
"V" -> Enum.random(String.graphemes(@vowels))
other -> other
end)
|> Enum.join()
end
defp check_token({:error, _} = e), do: e
defp check_token(token) do
String.split(token, "-")
|> Enum.any?(fn part -> Enum.member?(@blocklist, String.downcase(part)) end)
|> case do
true -> {:error, :blocked}
false -> {:ok, token}
end
end
defp check_token!(token) do
String.split(token, "-")
|> Enum.any?(fn part -> Enum.member?(@blocklist, String.downcase(part)) end)
|> case do
true -> raise "Generated token is blocked"
false -> token
end
end
end