Localize.Locale.Provider behaviour (Localize v0.5.0)

Copy Markdown View Source

Defines the behaviour for locale data providers.

A locale data provider is responsible for loading, storing, and retrieving CLDR locale data. Implementations may store data in any backing store such as :persistent_term, ETS, or the filesystem.

Callbacks

Implementing modules must define four callbacks:

  • load/1 — finds and retrieves locale data for a given locale.

  • store/2 — persists locale data to the provider's backing store.

  • loaded?/1 — checks whether a locale's data has been loaded and is available for use.

  • get/3 — retrieves a specific value from locale data by following a list of access keys, with optional fallback to parent locales.

Summary

Types

A locale reference: either a locale identifier atom or a language tag struct.

A locale identifier as an atom.

Callbacks

Returns whether this provider is permitted to download locale data from a remote source at runtime.

Retrieves a value from locale data by following a list of access keys.

Loads locale data for the given locale.

Returns whether locale data has been loaded and is available.

Stores locale data in the provider's backing store.

Functions

Returns whether runtime locale downloads are permitted for the given provider module.

Returns the base URL from which locale data files are downloaded.

Returns the default directory in which downloaded locale data is cached.

Downloads locale data for the given locale from locale_url/1.

Loads locale data with fallback through the CLDR parent chain.

Returns the directory in which downloaded locale data is cached.

Returns the file name for a locale's cached data file.

Returns the download URL for a given locale.

Returns the version segment used in cache paths and download URLs.

Types

locale()

@type locale() :: locale_id() | Localize.LanguageTag.t()

A locale reference: either a locale identifier atom or a language tag struct.

locale_id()

@type locale_id() :: atom()

A locale identifier as an atom.

Callbacks

allow_download?()

(optional)
@callback allow_download?() :: boolean()

Returns whether this provider is permitted to download locale data from a remote source at runtime.

Providers that never download (e.g. a database-backed provider) should return false. Providers that always have data locally available can simply not implement this callback — the default implementation reads Application.get_env(:localize, :allow_runtime_locale_download, false).

get(locale, list, t)

@callback get(locale(), list(), Keyword.t()) :: {:ok, term()} | {:error, term()}

Retrieves a value from locale data by following a list of access keys.

Navigates the locale data map using the provided list of keys, returning the value found at the end of the key path.

Arguments

  • locale is a locale identifier atom or a Localize.LanguageTag.t/0.

  • keys is a list of keys to traverse in the locale data map.

  • options is a keyword list of options. The default is [].

Options

  • :fallback is a boolean. When true, if the requested key path is not found in the given locale, the provider will attempt to find it in parent locales according to the CLDR locale inheritance chain. The default is false.

Returns

  • {:ok, value} if the key path resolves to a value.

  • {:error, reason} if the key path cannot be resolved.

load(locale)

@callback load(locale()) :: {:ok, map()} | {:error, Exception.t()}

Loads locale data for the given locale.

Finds the locale data for the given locale identifier or language tag, retrieves it from the data source, and returns the data as a map.

Arguments

Returns

  • {:ok, locale_data} where locale_data is a map of the locale's CLDR data.

  • {:error, Localize.UnknownLocaleError.t()} if the locale is not recognized.

loaded?(locale)

@callback loaded?(locale()) :: boolean()

Returns whether locale data has been loaded and is available.

Arguments

Returns

  • true if the locale data has been loaded and stored.

  • false otherwise.

store(locale_id, map)

@callback store(locale_id(), map()) :: :ok | {:error, term()}

Stores locale data in the provider's backing store.

Arguments

  • locale is a locale identifier atom.

  • locale_data is a map of locale data to store.

Returns

  • :ok on success.

  • {:error, reason} on failure.

Functions

allow_download?(provider_module \\ configured_provider())

@spec allow_download?(module()) :: boolean()

Returns whether runtime locale downloads are permitted for the given provider module.

If the provider module implements the optional allow_download?/0 callback, that implementation is called. Otherwise falls back to the :allow_runtime_locale_download application environment key (default false).

Arguments

  • provider_module is a module that implements the Localize.Locale.Provider behaviour. The default is the currently configured provider.

Returns

  • true if runtime downloads are permitted.

  • false otherwise.

base_url()

@spec base_url() :: String.t()

Returns the base URL from which locale data files are downloaded.

Returns

  • A string URL.

Examples

iex> Localize.Locale.Provider.base_url()
"https://elixir-localize.com/locales"

default_locale_cache_dir()

@spec default_locale_cache_dir() :: String.t()

Returns the default directory in which downloaded locale data is cached.

The default directory is located under the :localize application's priv directory at localize/locales.

Returns

  • A string path to the default locale cache directory.

Examples

iex> String.ends_with?(Localize.Locale.Provider.default_locale_cache_dir(), "localize/locales")
true

download_locale(locale_id)

@spec download_locale(locale_id()) :: {:ok, binary()} | {:error, Exception.t()}

Downloads locale data for the given locale from locale_url/1.

Uses Erlang's built-in :httpc to fetch the file. The downloaded content is returned as a binary and is not written to disk or decoded by this function.

Arguments

  • locale_id is a locale identifier atom.

Returns

  • {:ok, binary} with the raw downloaded file contents on success.

  • {:error, exception} if the locale could not be downloaded.

load_with_fallback(provider, locale)

@spec load_with_fallback(module(), locale()) ::
  {:ok, map(), locale_id()} | {:error, Exception.t()}

Loads locale data with fallback through the CLDR parent chain.

Attempts to load the requested locale via provider.load/1. If the load fails, walks up the CLDR locale inheritance chain (e.g. en-AUenund) trying each parent in turn. If the entire chain is exhausted without success, falls back to :en which is guaranteed to be present.

Returns {:ok, locale_data, resolved_locale_id} so the caller knows which locale was actually loaded.

Arguments

Returns

  • {:ok, locale_data, resolved_locale_id} on success.

  • {:error, exception} if even the :en fallback fails (should not happen in normal operation).

locale_cache_dir()

@spec locale_cache_dir() :: String.t()

Returns the directory in which downloaded locale data is cached.

The directory is resolved from the :locale_cache_dir application environment key for :localize, falling back to default_locale_cache_dir/0 when unset.

Returns

  • A string path to the locale cache directory.

Examples

iex> is_binary(Localize.Locale.Provider.locale_cache_dir())
true

locale_file_name(locale_id)

@spec locale_file_name(locale_id()) :: String.t()

Returns the file name for a locale's cached data file.

Arguments

  • locale_id is a locale identifier atom.

Returns

  • A string file name of the form "{locale_id}.etf".

Examples

iex> Localize.Locale.Provider.locale_file_name(:en)
"en.etf"

locale_url(locale_id)

@spec locale_url(locale_id()) :: String.t()

Returns the download URL for a given locale.

The URL is versioned by the current Localize.version/0 so that each Localize release downloads from its own path.

Arguments

  • locale_id is a locale identifier atom.

Returns

  • A string URL from which the locale's data file can be downloaded.

Examples

iex> url = Localize.Locale.Provider.locale_url(:en)
iex> String.starts_with?(url, "https://elixir-localize.com/locales/")
true
iex> String.ends_with?(url, "/en.etf")
true

version_segment()

@spec version_segment() :: String.t()

Returns the version segment used in cache paths and download URLs.

Returns

  • A string of the form "v{major}.{minor}.{patch}" matching Localize.version/0 with a v prefix.