63 lines
2.3 KiB
Elixir
63 lines
2.3 KiB
Elixir
defmodule UkraineTaxidEx.BaseValidator do
|
|
@callback validate(code :: String.t()) ::
|
|
{:ok, code :: String.t()}
|
|
| {:error,
|
|
:length_too_short | :length_too_long | :invalid_length | :invalid_checksum}
|
|
@callback violates_length?(code :: String.t()) :: boolean
|
|
@callback violates_length_too_short?(code :: String.t()) :: boolean
|
|
@callback violates_length_too_long?(code :: String.t()) :: boolean
|
|
@callback violates_checksum?(code :: String.t()) :: boolean
|
|
|
|
defmacro __using__(_) do
|
|
quote do
|
|
alias UkraineTaxidEx.BaseValidator
|
|
|
|
@behaviour UkraineTaxidEx.BaseValidator
|
|
import UkraineTaxidEx.Commons, only: [digits: 1, digits_and_check_digit: 1, error: 1, ok: 1]
|
|
|
|
@impl BaseValidator
|
|
@spec validate(String.t()) ::
|
|
{:ok, String.t()}
|
|
| {:error,
|
|
:length_too_short | :length_too_long | :invalid_length | :invalid_checksum}
|
|
def validate(string) do
|
|
cond do
|
|
violates_length_too_short?(string) -> error(:length_too_short)
|
|
violates_length_too_long?(string) -> error(:length_too_long)
|
|
violates_checksum?(string) -> error(:invalid_checksum)
|
|
true -> ok(string)
|
|
end
|
|
end
|
|
|
|
@doc "Check whether a given EDRPOU violates the required length"
|
|
@impl BaseValidator
|
|
@spec violates_length?(code :: String.t()) :: boolean
|
|
def violates_length?(code), do: String.length(code) != length()
|
|
|
|
@doc "Check whether a given EDRPOU too short"
|
|
@impl BaseValidator
|
|
@spec violates_length_too_short?(code :: String.t()) :: boolean
|
|
def violates_length_too_short?(code), do: String.length(code) < length()
|
|
|
|
@doc "Check whether a given EDRPOU too long"
|
|
@impl BaseValidator
|
|
@spec violates_length_too_long?(code :: String.t()) :: boolean
|
|
def violates_length_too_long?(code), do: String.length(code) > length()
|
|
|
|
@doc "Check whether a given EDRPOU has correct checksum"
|
|
@impl BaseValidator
|
|
@spec violates_checksum?(code :: String.t()) :: boolean
|
|
def violates_checksum?(code) do
|
|
{digits, check_digit} =
|
|
code
|
|
|> digits()
|
|
|> digits_and_check_digit()
|
|
|
|
check_sum = check_sum(digits)
|
|
|
|
check_sum != check_digit
|
|
end
|
|
end
|
|
end
|
|
end
|