# `Localize.PhoneNumber`
[🔗](https://github.com/elixir-localize/localize_phone_number/blob/v0.1.0/lib/localize/phone_number.ex#L1)

Elixir interface to Google's libphonenumber library via NIF.

Provides phone number parsing, formatting, and validation with
locale-aware territory defaults. The default territory is derived
from `Localize.get_locale/0` using the `localize` dependency.

All functions operate on `Localize.PhoneNumber.Number` structs
returned by `parse/2`.

# `format_type`

```elixir
@type format_type() :: :e164 | :international | :national | :rfc3966
```

# `phone_number_type`

```elixir
@type phone_number_type() ::
  :fixed_line
  | :mobile
  | :fixed_line_or_mobile
  | :toll_free
  | :premium_rate
  | :shared_cost
  | :voip
  | :personal_number
  | :pager
  | :uan
  | :voicemail
  | :unknown
```

# `t`

```elixir
@type t() :: Localize.PhoneNumber.Number.t()
```

# `available?`

```elixir
@spec available?() :: boolean()
```

Returns whether the NIF backend is available.

### Returns

* `true` if the NIF shared library was loaded successfully.

* `false` if the NIF is not compiled or libphonenumber is missing.

### Examples

    iex> is_boolean(Localize.PhoneNumber.available?())
    true

# `parse`

```elixir
@spec parse(
  String.t(),
  keyword()
) :: {:ok, t()} | {:error, String.t()}
```

Parses a phone number string into a `Localize.PhoneNumber.Number` struct.

### Arguments

* `number_string` is the phone number string to parse. It can be in
  national or international format.

### Options

* `:territory` is an explicit ISO 3166-1 alpha-2 territory code
  (e.g., `"US"`, `"GB"`, or an atom like `:US`). Used as the default
  territory when the number is not in international format.

* `:locale` is a locale identifier used to derive the default territory.
  Accepts a string (e.g., `"en-US"`), an atom (e.g., `:en_US`), or a
  `Localize.LanguageTag.t()` struct. The territory is extracted from
  the locale.

When neither `:territory` nor `:locale` is given, the territory is
derived from `Localize.get_locale/0`.

### Returns

* `{:ok, phone_number}` where `phone_number` is a
  `Localize.PhoneNumber.Number` struct.

* `{:error, reason}` if the number cannot be parsed.

### Examples

    iex> {:ok, phone_number} = Localize.PhoneNumber.parse("+1 650-253-0000")
    iex> phone_number.country_code
    1

    iex> {:ok, phone_number} = Localize.PhoneNumber.parse("020 7946 0958", territory: "GB")
    iex> phone_number.country_code
    44

# `possible?`

```elixir
@spec possible?(t()) :: boolean()
```

Returns whether a parsed phone number is a possible number.

A possible number has a plausible length for its territory and type
but may not actually be an allocated or valid number.

### Arguments

* `phone_number` is a `Localize.PhoneNumber.Number` struct.

### Returns

* `true` if the phone number is possible.

* `false` otherwise.

### Examples

    iex> {:ok, phone_number} = Localize.PhoneNumber.parse("+1 650-253-0000")
    iex> Localize.PhoneNumber.possible?(phone_number)
    true

# `territory`

```elixir
@spec territory(t()) :: String.t() | nil
```

Returns the territory code for a parsed phone number.

### Arguments

* `phone_number` is a `Localize.PhoneNumber.Number` struct.

### Returns

* A two-letter ISO 3166-1 alpha-2 territory code string
  (e.g., `"US"`, `"GB"`).

* `nil` if the territory cannot be determined.

### Examples

    iex> {:ok, phone_number} = Localize.PhoneNumber.parse("+1 650-253-0000")
    iex> Localize.PhoneNumber.territory(phone_number)
    "US"

# `to_string`

```elixir
@spec to_string(t(), format_type()) :: {:ok, String.t()} | {:error, String.t()}
```

Formats a parsed phone number as a string in the specified format.

### Arguments

* `phone_number` is a `Localize.PhoneNumber.Number` struct
  returned by `parse/2`.

* `format_type` is one of `:e164`, `:international`, `:national`,
  or `:rfc3966`. The default is `:international`.

### Returns

* `{:ok, formatted_string}` on success.

* `{:error, reason}` on failure.

### Examples

    iex> {:ok, phone_number} = Localize.PhoneNumber.parse("+1 650-253-0000")
    iex> Localize.PhoneNumber.to_string(phone_number, :e164)
    {:ok, "+16502530000"}

    iex> {:ok, phone_number} = Localize.PhoneNumber.parse("+1 650-253-0000")
    iex> Localize.PhoneNumber.to_string(phone_number, :international)
    {:ok, "+1 650-253-0000"}

    iex> {:ok, phone_number} = Localize.PhoneNumber.parse("+1 650-253-0000")
    iex> Localize.PhoneNumber.to_string(phone_number)
    {:ok, "+1 650-253-0000"}

# `type`

```elixir
@spec type(t()) :: phone_number_type()
```

Returns the phone number type.

### Arguments

* `phone_number` is a `Localize.PhoneNumber.Number` struct.

### Returns

* An atom representing the type: `:fixed_line`, `:mobile`,
  `:fixed_line_or_mobile`, `:toll_free`, `:premium_rate`,
  `:shared_cost`, `:voip`, `:personal_number`, `:pager`,
  `:uan`, `:voicemail`, or `:unknown`.

### Examples

    iex> {:ok, phone_number} = Localize.PhoneNumber.parse("+1 650-253-0000")
    iex> Localize.PhoneNumber.type(phone_number)
    :fixed_line_or_mobile

# `valid?`

```elixir
@spec valid?(t()) :: boolean()
```

Returns whether a parsed phone number is valid.

A valid number has the correct length and pattern for its territory
and number type.

### Arguments

* `phone_number` is a `Localize.PhoneNumber.Number` struct.

### Returns

* `true` if the phone number is valid.

* `false` otherwise.

### Examples

    iex> {:ok, phone_number} = Localize.PhoneNumber.parse("+1 650-253-0000")
    iex> Localize.PhoneNumber.valid?(phone_number)
    true

# `valid_for_territory?`

```elixir
@spec valid_for_territory?(t(), String.t()) :: boolean()
```

Returns whether a parsed phone number is valid for a specific territory.

### Arguments

* `phone_number` is a `Localize.PhoneNumber.Number` struct.

* `territory` is an ISO 3166-1 alpha-2 territory code string
  (e.g., `"US"`, `"GB"`).

### Returns

* `true` if the phone number is valid for the given territory.

* `false` otherwise.

### Examples

    iex> {:ok, phone_number} = Localize.PhoneNumber.parse("+1 650-253-0000")
    iex> Localize.PhoneNumber.valid_for_territory?(phone_number, "US")
    true

---

*Consult [api-reference.md](api-reference.md) for complete listing*
