Localize.PersonName behaviour (Localize Person Names v0.1.0)

Copy Markdown View Source

Locale-aware person name formatting built on the Unicode CLDR person names specification.

A person name is represented as a Localize.PersonName.t/0 struct containing name parts (title, given name, surname, etc.) plus optional locale and ordering preferences.

Formatting is driven by the locale's CLDR person name patterns, which vary by length (:short, :medium, :long), usage (:addressing, :referring, :monogram), formality (:formal, :informal), and name order (:given_first, :surname_first, :sorting).

Primary API

Integrating existing structs

Any struct can participate in person name formatting in two ways:

  • Implement the Localize.PersonName.Convertible protocol — a single function that returns a Localize.PersonName struct. Recommended for most cases, including third-party structs.

  • Implement the Localize.PersonName behaviour — eleven callbacks on the struct's module, each returning one name field. Use this when the struct's module is under your control and you want individual name fields exposed as module functions.

When the formatter receives a struct, it first looks for a Convertible protocol implementation; if none is found, it falls back to the behaviour callbacks via cast_to_person_name/1.

Summary

Types

Standard error response.

Valid :formality option.

Valid :format option.

A keyword list of options for to_string/2 and to_iodata/2.

Valid :order option.

t()

A PersonName struct containing the fields supported for person name formatting.

Valid :usage option.

Callbacks

Return the credentials as a String.t/0 or nil for the given struct.

Return the generation as a String.t/0 or nil for the given struct.

Return the given name as a String.t/0 or nil for the given struct.

Return the informal given name as a String.t/0 or nil for the given struct.

Return the locale or nil for the given struct.

Return the other given names as a String.t/0 or nil for the given struct.

Return the other surnames as a String.t/0 or nil for the given struct.

Return the preferred name order for the given struct.

Return the surname as a String.t/0 or nil for the given struct.

Return the surname prefix as a String.t/0 or nil for the given struct.

Return the title as a String.t/0 or nil for the given struct.

Functions

Casts any struct that implements the Localize.PersonName behaviour into a Localize.PersonName.t/0 struct.

Returns a Localize.PersonName.t/0 struct crafted from a keyword list of attributes.

Returns a formatted person name as iodata.

Returns a formatted person name as a string.

Same as to_string/2 but raises on error.

Types

error_message()

@type error_message() :: String.t() | {module(), String.t()}

Standard error response.

formality()

@type formality() :: :formal | :informal

Valid :formality option.

format()

@type format() :: :short | :medium | :long

Valid :format option.

format_option()

@type format_option() ::
  {:format, format()}
  | {:order, name_order()}
  | {:usage, usage()}
  | {:formality, formality()}
  | {:locale, Localize.LanguageTag.t() | atom() | String.t()}
  | {:locale_switching, boolean()}

An option to to_string/2 and to_iodata/2.

format_options()

@type format_options() :: [format_option()]

A keyword list of options for to_string/2 and to_iodata/2.

name_order()

@type name_order() :: :given_first | :surname_first | :sorting

Valid :order option.

t()

@type t() :: %Localize.PersonName{
  credentials: String.t() | nil,
  generation: String.t() | nil,
  given_name: String.t() | nil,
  informal_given_name: String.t() | nil,
  locale: Localize.LanguageTag.t() | nil,
  other_given_names: String.t() | nil,
  other_surnames: String.t() | nil,
  preferred_order: name_order() | nil,
  surname: String.t() | nil,
  surname_prefix: String.t() | nil,
  title: String.t() | nil
}

A PersonName struct containing the fields supported for person name formatting.

usage()

@type usage() :: :addressing | :referring | :monogram

Valid :usage option.

Callbacks

credentials(name)

@callback credentials(name :: struct()) :: String.t() | nil

Return the credentials as a String.t/0 or nil for the given struct.

generation(name)

@callback generation(name :: struct()) :: String.t() | nil

Return the generation as a String.t/0 or nil for the given struct.

given_name(name)

@callback given_name(name :: struct()) :: String.t() | nil

Return the given name as a String.t/0 or nil for the given struct.

informal_given_name(name)

@callback informal_given_name(name :: struct()) :: String.t() | nil

Return the informal given name as a String.t/0 or nil for the given struct.

locale(name)

@callback locale(name :: struct()) :: Localize.LanguageTag.t() | nil

Return the locale or nil for the given struct.

other_given_names(name)

@callback other_given_names(name :: struct()) :: String.t() | nil

Return the other given names as a String.t/0 or nil for the given struct.

other_surnames(name)

@callback other_surnames(name :: struct()) :: String.t() | nil

Return the other surnames as a String.t/0 or nil for the given struct.

preferred_order(name)

@callback preferred_order(name :: struct()) :: name_order()

Return the preferred name order for the given struct.

surname(name)

@callback surname(name :: struct()) :: String.t() | nil

Return the surname as a String.t/0 or nil for the given struct.

surname_prefix(name)

@callback surname_prefix(name :: struct()) :: String.t() | nil

Return the surname prefix as a String.t/0 or nil for the given struct.

title(name)

@callback title(name :: struct()) :: String.t() | nil

Return the title as a String.t/0 or nil for the given struct.

Functions

cast_to_person_name(name)

@spec cast_to_person_name(struct()) :: t()

Casts any struct that implements the Localize.PersonName behaviour into a Localize.PersonName.t/0 struct.

Arguments

Returns

new(attributes \\ [])

@spec new(attributes :: Keyword.t()) :: {:ok, t()} | {:error, error_message()}

Returns a Localize.PersonName.t/0 struct crafted from a keyword list of attributes.

Arguments

Options

  • :given_name is a person's given name. This is a required attribute. The value is any String.t/0.

  • :title is a person's title such as "Mr." or "Dr.".

  • :other_given_names is any String.t/0 or nil. The default is nil.

  • :informal_given_name is any String.t/0 or nil. The default is nil.

  • :surname_prefix is any String.t/0 or nil. The default is nil.

  • :surname is any String.t/0 or nil. The default is nil.

  • :other_surnames is any String.t/0 or nil. The default is nil.

  • :generation is any String.t/0 or nil. The default is nil.

  • :credentials is any String.t/0 or nil. The default is nil.

  • :locale is a locale identifier or Localize.LanguageTag.t/0 or nil. The default is nil.

  • :preferred_order is one of :given_first, :surname_first or :sorting. The default is nil, meaning that the name order is derived from the name's locale and the formatting locale.

Returns

  • {:ok, person_name_struct} or

  • {:error, reason}.

Examples

iex> Localize.PersonName.new(title: "Mr.", given_name: "José", surname: "Valim", credentials: "Ph.D.", locale: "pt")
{:ok,
 %Localize.PersonName{
   title: "Mr.",
   given_name: "José",
   other_given_names: nil,
   informal_given_name: nil,
   surname_prefix: nil,
   surname: "Valim",
   other_surnames: nil,
   generation: nil,
   credentials: "Ph.D.",
   preferred_order: nil,
   locale: %Localize.LanguageTag{
     language: :pt,
     language_subtags: [],
     script: :Latn,
     territory: :BR,
     language_variants: [],
     locale: %{},
     transform: %{},
     extensions: %{},
     private_use: [],
     requested_locale_id: "pt",
     canonical_locale_id: "pt",
     cldr_locale_id: :pt
   }
 }}

iex> Localize.PersonName.new(surname: "Valim")
{:error, "Person Name requires at least a :given_name"}

to_iodata(person_name, options \\ [])

@spec to_iodata(person_name :: struct(), options :: format_options()) ::
  {:ok, :erlang.iodata()} | {:error, error_message()}

Returns a formatted person name as iodata.

Accepts the same arguments and options as to_string/2.

Returns

  • {:ok, iodata} or

  • {:error, reason}.

Examples

iex> {:ok, jose} = Localize.PersonName.new(title: "Mr.", given_name: "José", surname: "Valim", credentials: "Ph.D.", locale: "pt")
iex> Localize.PersonName.to_iodata(jose)
{:ok, ["José"]}

iex> {:ok, jose} = Localize.PersonName.new(title: "Mr.", given_name: "José", surname: "Valim", credentials: "Ph.D.", locale: "pt")
iex> Localize.PersonName.to_iodata(jose, format: :long, formality: :formal)
{:ok, ["Mr.", " ", "Valim"]}

to_iodata!(person_name, options \\ [])

@spec to_iodata!(person_name :: struct(), options :: format_options()) ::
  :erlang.iodata() | no_return()

Same as to_iodata/2 but raises on error.

to_string(name, options \\ [])

@spec to_string(name :: struct(), options :: format_options()) ::
  {:ok, String.t()} | {:error, error_message()}

Returns a formatted person name as a string.

Arguments

Options

  • :format is the relative length of a formatted name. The valid values are :short, :medium and :long. The default is derived from the formatting locale's preferences.

  • :usage indicates how the formatted name is used. The valid values are :addressing, :referring or :monogram. The default is :addressing.

  • :formality indicates the formality of usage. The valid values are :formal and :informal. The default is derived from the formatting locale's preferences.

  • :order expresses preference for name part order. The valid values are :given_first, :surname_first and :sorting. The default is based on the person name struct and the formatting locale.

  • :locale is a locale identifier or Localize.LanguageTag.t/0. The default is Localize.get_locale().

  • :locale_switching when true, switches the formatting locale to match the name's script when they differ. For example, a Latin-script name formatted in a Japanese locale will use Latin-based formatting patterns. The default is false for compatibility with the CLDR test data. See TODO.md for details.

Returns

  • {:ok, formatted_name} or

  • {:error, reason}.

Examples

iex> {:ok, jose} = Localize.PersonName.new(title: "Mr.", given_name: "José", surname: "Valim", credentials: "Ph.D.", locale: "pt")
iex> Localize.PersonName.to_string(jose)
{:ok, "José"}

iex> {:ok, jose} = Localize.PersonName.new(title: "Mr.", given_name: "José", surname: "Valim", credentials: "Ph.D.", locale: "pt")
iex> Localize.PersonName.to_string(jose, format: :long, formality: :formal, usage: :referring)
{:ok, "Mr. José Valim Ph.D."}

to_string!(name, options \\ [])

@spec to_string!(name :: struct(), options :: format_options()) ::
  String.t() | no_return()

Same as to_string/2 but raises on error.

Examples

iex> {:ok, jose} = Localize.PersonName.new(title: "Mr.", given_name: "José", surname: "Valim", credentials: "Ph.D.", locale: "pt")
iex> Localize.PersonName.to_string!(jose)
"José"

iex> {:ok, jose} = Localize.PersonName.new(title: "Mr.", given_name: "José", surname: "Valim", credentials: "Ph.D.", locale: "pt")
iex> Localize.PersonName.to_string!(jose, format: :long, formality: :formal, usage: :referring)
"Mr. José Valim Ph.D."