Current section

Files

Jump to
brcpfcnpj lib changeset.ex
Raw

lib/changeset.ex

defmodule Brcpfcnpj.Changeset do
@moduledoc """
Define funções para serem utilizadas em conjunto com a API de changeset do Ecto.
"""
@type t :: %{
changes: %{required(atom()) => term()},
errors: [{atom(), error()}],
valid?: boolean()
}
@type error :: {atom, error_message}
@type error_message :: String.t() | {String.t(), Keyword.t()}
@doc """
Valida se essa mudação é um cnpj válido.
## Options
* `:message` - A mensagem em caso de erro, o default é "Invalid Cnpj"
## Examples
validate_cnpj(changeset, :cnpj)
"""
@spec validate_cnpj(t, atom, Keyword.t()) :: t
def validate_cnpj(changeset, field, opts \\ []) when is_atom(field) do
validate(changeset, field, fn value ->
cond do
Brcpfcnpj.cnpj_valid?(%Cnpj{number: value}) -> []
true -> [{field, message(opts, {"Invalid Cnpj", validation: :cnpj})}]
end
end)
end
@doc """
Valida se essa mudação é um cpf válido.
## Options
* `:message` - A mensagem em caso de erro, o default é "Invalid Cpf"
## Examples
validate_cpf(changeset, :cpf)
"""
@spec validate_cpf(t, atom, Keyword.t()) :: t
def validate_cpf(changeset, field, opts \\ []) when is_atom(field) do
validate(changeset, field, fn value ->
cond do
Brcpfcnpj.cpf_valid?(%Cpf{number: value}) -> []
true -> [{field, message(opts, {"Invalid Cpf", validation: :cpf})}]
end
end)
end
defp validate(changeset, field, validator) do
%{changes: changes, errors: errors} = changeset
value = Map.get(changes, field)
new = if is_nil(value), do: [], else: validator.(value)
case new do
[] -> changeset
[_ | _] -> %{changeset | errors: new ++ errors, valid?: false}
end
end
defp message(opts, default) do
message = Keyword.get(opts, :message, default)
format_message(message)
end
defp format_message({_, _} = msg), do: msg
defp format_message(msg) when is_binary(msg), do: {msg, []}
end