Packages
surgex
1.4.0
6.0.1
6.0.0
5.1.1
5.1.0
5.0.0
5.0.0-git-015aa39a
4.15.2
4.15.1
4.15.1-git-98b3
4.15.0
4.15.0-git-943e
4.15.0-git-5806
4.14.1
4.14.0
4.13.1
4.13.0
4.12.0
4.11.0
4.11.0-git-97d4
4.11.0-git-14c8
4.10.0
4.10.0-git-37f2
4.9.0
4.9.0-git-9d5f
4.8.1-git-80a7
4.8.0
4.8.0-git-fbda
4.8.0-git-e058
4.7.0
4.7.0-git-5414
4.6.1
4.6.0
4.5.0
4.4.0
4.3.0
4.2.1
4.2.0
4.1.1
4.1.1-git-9f6b
4.1.1-git-6f0cd
4.1.0
4.1.0-git-e934
4.1.0-git-8c28
4.1.0-git-56a9
4.1.0-git-55fd
4.0.0
3.2.8
3.2.7
3.2.6
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
retired
3.1.0
3.0.0
2.24.1
2.24.0
retired
2.23.0
2.22.0
2.21.0
2.20.1
2.20.0
2.19.0
2.18.1
2.18.0
2.17.0
2.16.0
2.15.0
2.14.0
2.13.0
2.12.1
2.12.0
2.11.0
2.10.0
2.9.0
2.8.0
2.7.0
2.6.0
2.5.1
2.5.0
2.4.0
retired
2.3.0
2.2.1
2.2.0
2.1.1
2.1.0
2.0.0
1.6.0
1.5.2
1.5.1
1.5.0
1.4.0
1.3.1
retired
1.3.0
retired
1.2.1
1.2.0
1.1.0
1.0.0
0.5.2
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
All Things Elixir @ Surge Ventures Inc, the creators of Fresha
Current section
Files
Jump to
Current section
Files
lib/surgex/phone_number.ex
defmodule Surgex.PhoneNumber do
@moduledoc false
@behaviour Ecto.Type
defstruct [:e164]
defimpl Inspect do
def inspect(%{e164: e164}, _opts) do
~s(#Surgex.PhoneNumber<#{e164}>)
end
end
defimpl String.Chars do
def to_string(phone_number = %{e164: e164}) do
alias Surgex.PhoneNumber
PhoneNumber.format(phone_number) || Kernel.to_string(e164)
rescue
ArgumentError -> Kernel.to_string(e164)
end
end
def type, do: :string
def cast(phone_number = %__MODULE__{}), do: {:ok, phone_number}
def cast(string) when is_binary(string) do
normalized_string =
string
|> String.replace(~r/[-.() ]/, "")
|> String.replace(~r/^\+?0*/, "")
with true <- Regex.match?(~r/^\d+$/, normalized_string),
{:ok, ex_phone_number} <- ExPhoneNumber.parse("+" <> normalized_string, nil),
true <- ExPhoneNumber.is_valid_number?(ex_phone_number),
"+" <> e164_string <- ExPhoneNumber.format(ex_phone_number, :e164),
{e164_integer, ""} <- Integer.parse(e164_string)
do
{:ok, %__MODULE__{e164: e164_integer}}
else
_ -> :error
end
end
def cast(nil), do: {:ok, nil}
def cast(_), do: :error
def load(e164_string) when is_binary(e164_string) do
case Integer.parse(e164_string) do
{e164_integer, ""} ->
{:ok, %__MODULE__{e164: e164_integer}}
_ ->
:error
end
end
def dump(%__MODULE__{e164: e164}) when is_integer(e164), do: {:ok, Integer.to_string(e164)}
def dump(_), do: :error
def format(nil), do: nil
def format(%__MODULE__{e164: e164}, format \\ :international) do
with e164_integer when is_integer(e164_integer) <- e164,
{:ok, ex_phone_number} <- ExPhoneNumber.parse("+" <> Integer.to_string(e164_integer), nil)
do
ExPhoneNumber.format(ex_phone_number, format)
else
_ -> raise(ArgumentError, "Invalid phone number: #{inspect e164}")
end
end
end