2024-12-11 08:02:07 +00:00
|
|
|
defmodule UkraineTaxidEx.BaseParser do
|
2024-12-12 06:32:31 +00:00
|
|
|
@type options :: [normalize?: boolean, clean?: boolean]
|
2024-12-11 08:02:07 +00:00
|
|
|
@callback parse(string :: String.t(), options :: options()) :: {:ok, term} | {:error, atom}
|
|
|
|
|
|
|
|
defmacro __using__(_) do
|
|
|
|
quote do
|
|
|
|
@behaviour UkraineTaxidEx.BaseParser
|
|
|
|
|
|
|
|
alias UkraineTaxidEx.BaseParser
|
2024-12-13 02:17:30 +00:00
|
|
|
|
|
|
|
@type string_or_ok() :: String.t() | {:ok, String.t()}
|
|
|
|
@type struct_or_error() :: {:ok, term} | {:error, atom()}
|
|
|
|
|
|
|
|
@struct_module Module.split(__MODULE__) |> Enum.slice(0..-2//1) |> Module.safe_concat()
|
|
|
|
# def struct_module(), do: @struct_module
|
|
|
|
|
|
|
|
defp to_struct(map), do: struct(@struct_module, map)
|
|
|
|
|
|
|
|
@impl BaseParser
|
|
|
|
@spec parse(data :: string_or_ok, options :: BaseParser.options()) :: struct_or_error()
|
|
|
|
def parse(data, options \\ [normalize?: false, clean?: false])
|
|
|
|
def parse({:ok, string}, options), do: parse(string, options)
|
|
|
|
def parse({:error, error}, _options), do: {:error, error}
|
|
|
|
|
|
|
|
def parse(string, options) do
|
|
|
|
length = (Keyword.get(options, :normalize?, false) && length()) || 0
|
|
|
|
clean? = Keyword.get(options, :clean?, false)
|
|
|
|
|
|
|
|
string
|
|
|
|
|> digits(length, clean?)
|
|
|
|
|> undigits()
|
|
|
|
|> validate()
|
|
|
|
|> generate()
|
|
|
|
end
|
|
|
|
|
|
|
|
defp generate({:error, error}), do: {:error, error}
|
2024-12-11 08:02:07 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|