Skip to content

Instantly share code, notes, and snippets.

@phanmn
Created August 19, 2024 04:14
Show Gist options
  • Save phanmn/e52ecceb1c810218b67b988b52c23c99 to your computer and use it in GitHub Desktop.
Save phanmn/e52ecceb1c810218b67b988b52c23c99 to your computer and use it in GitHub Desktop.
Absinthe Graphql Schema Scalar Phone Number
defmodule AppWeb.Graphql.Schema.Types.Custom.PhoneNumber do
@moduledoc """
The phone number scalar type.
"""
use Absinthe.Schema.Notation
require Logger
require OK
scalar :phone_number, name: "PhoneNumber", open_ended: true do
description("""
Phone number in e164 format
""")
serialize(&encode/1)
parse(&decode/1)
end
@spec decode(Absinthe.Blueprint.Input.String.t()) :: {:ok, term()} | :error
@spec decode(Absinthe.Blueprint.Input.Integer.t()) :: {:ok, term()} | :error
@spec decode(Absinthe.Blueprint.Input.Null.t()) :: {:ok, nil}
defp decode(%Absinthe.Blueprint.Input.String{value: value}) do
cast(value)
end
defp decode(%Absinthe.Blueprint.Input.Integer{value: value}) do
cast(value)
end
defp decode(%Absinthe.Blueprint.Input.Null{}) do
{:ok, nil}
end
defp decode(_) do
:error
end
defp encode(value) do
value
end
def cast(integer) when is_integer(integer), do: Kernel.to_string(integer) |> cast()
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) do
{:ok, e164_string}
else
_ -> :error
end
end
def cast(nil), do: {:ok, nil}
def cast(_), do: :error
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment