Created
July 8, 2021 14:15
-
-
Save thiamsantos/b39a5871b9dbf62f45d3950934549025 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule App.PhoneNumber do | |
use Ecto.Type | |
defstruct country_code: nil, | |
national_number: nil, | |
extension: nil, | |
italian_leading_zero: nil, | |
number_of_leading_zeros: nil, | |
raw_input: nil, | |
country_code_source: nil, | |
preferred_domestic_carrier_code: nil | |
def parse(value) when is_binary(value) do | |
case ExPhoneNumber.parse(value, "") do | |
{:ok, phone_number} -> | |
fields = Map.from_struct(phone_number) | |
{:ok, struct!(__MODULE__, fields)} | |
_ -> | |
:error | |
end | |
end | |
def parse!(value) do | |
case parse(value) do | |
{:ok, phone_number} -> | |
phone_number | |
:error -> | |
raise ArgumentError, | |
"cannot parse #{inspect(value)} as phone number, reason: :invalid_format" | |
end | |
end | |
def to_e164(%__MODULE__{} = phone_number) do | |
fields = Map.from_struct(phone_number) | |
ExPhoneNumber.Model.PhoneNumber | |
|> struct!(fields) | |
|> ExPhoneNumber.format(:e164) | |
end | |
def to_national(%__MODULE__{} = phone_number) do | |
fields = Map.from_struct(phone_number) | |
ExPhoneNumber.Model.PhoneNumber | |
|> struct!(fields) | |
|> ExPhoneNumber.format(:national) | |
end | |
@impl true | |
def type, do: :string | |
@impl true | |
def cast("+" <> _phone = value) when is_binary(value) do | |
parse(value) | |
end | |
def cast(value) when is_binary(value) do | |
parse("+#{value}") | |
end | |
@impl true | |
def cast(%__MODULE__{} = phone_number), do: {:ok, phone_number} | |
@impl true | |
def cast(_), do: :error | |
@impl true | |
def load(value) when is_binary(value) do | |
parse(value) | |
end | |
@impl true | |
def dump(%__MODULE__{} = phone_number), do: {:ok, to_e164(phone_number)} | |
@impl true | |
def dump(_), do: :error | |
end | |
defimpl Inspect, for: App.PhoneNumber do | |
def inspect(phone_number, _opts) do | |
"#PhoneNumber<" <> App.PhoneNumber.to_e164(phone_number) <> ">" | |
end | |
end | |
defimpl Jason.Encoder, for: App.PhoneNumber do | |
def encode(phone_number, opts) do | |
Jason.Encode.string(App.PhoneNumber.to_e164(phone_number), opts) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment