Current section
Files
Jump to
Current section
Files
lib/mobile_number.ex
defmodule MobileNumberFormat.MobileNumber do
use Ecto.Schema
import Ecto.Changeset
@primary_key false
embedded_schema do
field :country_code, :string
field :country_calling_code, :string
field :national_number, :string
field :cleaned_national_number, :string
end
@fields ~w(country_calling_code national_number)a
def changeset(mobile, attrs) do
mobile
|> cast(attrs, @fields)
|> validate_required(@fields)
|> maybe_validate_and_clean()
end
defp maybe_validate_and_clean(changeset) do
changed? =
[:country_calling_code, :national_number]
|> Enum.any?(&Map.has_key?(changeset.changes, &1))
if changed? do
validate_and_clean_mobile(changeset)
else
changeset
end
end
defp validate_and_clean_mobile(changeset) do
parsed_data =
MobileNumberFormat.parse(%{
country_code: fetch_field!(changeset, :country_code),
country_calling_code: fetch_field!(changeset, :country_calling_code),
national_number: fetch_field!(changeset, :national_number)
})
case parsed_data do
:invalid_country_code ->
add_error(changeset, :invalid_country_code, "country is not valid")
:invalid_country_calling_code ->
add_error(changeset, :invalid_country_calling_code, "country calling code is not valid")
:invalid_number ->
add_error(changeset, :invalid_number, "mobile number is not valid")
:insufficient_data ->
raise "unexpected error"
parsed_data ->
{:ok, %{
country_code: country_code,
country_calling_code: country_calling_code,
national_number: cleaned_national_number
}} = parsed_data
change(changeset, %{
country_code: country_code,
country_calling_code: country_calling_code,
cleaned_national_number: cleaned_national_number
})
end
end
end