# `Localize.Unit.Preference`
[🔗](https://github.com/elixir-localize/localize/blob/v1.4.0/lib/localize/unit/preference.ex#L1)

Returns the preferred units for a given unit, territory, and usage.

In many cultures, the common unit of measure for some unit categories
varies based upon the usage. For example, when describing length in
the US, the units vary by context:

* road distance — miles for larger distances, feet for smaller
* person height — feet and inches
* snowfall — inches

This module provides functions to look up CLDR preference data for
different use cases in different territories.

# `known_usages`

```elixir
@spec known_usages() :: [atom(), ...]
```

Returns the unit usages CLDR defines preferences for.

A usage names the context a quantity is being measured in — `:person_height`
and `:road` are both lengths, but a locale prefers different units for them.

### Returns

* A sorted list of usage atoms.

### Examples

    iex> usages = Localize.Unit.Preference.known_usages()
    iex> :fluid in usages
    true

    iex> :person_height in Localize.Unit.Preference.known_usages()
    true

# `preferred_units`

```elixir
@spec preferred_units(Localize.Unit.t(), Keyword.t()) ::
  {:ok, [atom()], Keyword.t()} | {:error, Exception.t()}
```

Returns the preferred units for a given unit, territory, and usage.

The unit's value is converted to the base unit for its category and
compared against the `geq` (greater-than-or-equal) thresholds in the
preference data to select the appropriate unit set.

### Arguments

* `unit` is a `t:Localize.Unit.t/0` struct.

* `options` is a keyword list of options.

### Options

* `:usage` is the unit usage context as an atom (e.g., `:person_height`,
  `:road`). The default is `:default`.

* `:territory` is a territory code atom (e.g., `:US`, `:GB`). The
  default is derived from the current locale.

* `:locale` is a locale identifier. Its territory is used when
  `:territory` is not given, and its `u` extension keywords are honoured
  in TR35's order `mu > ms > rg > territory`: `-u-mu` names the unit
  outright, `-u-ms` a measurement system and `-u-rg` a region to take
  preferences from. CLDR supports `-u-mu` for temperature only, and its
  three values are `celsius`, `kelvin` and `fahrenhe` — BCP-47 caps a
  key's value at eight characters, so Fahrenheit is spelled `fahrenhe`.
  A `-u-mu` unit that is not convertible from the unit given is ignored.

* `:scope` is `:small` or `nil`. Forward-compatible placeholder for
  CLDR's planned scope-keyed preferences (small-quantity contexts);
  accepted but currently has no effect because no `<unitPreference>`
  in the shipped CLDR data carries a `scope` attribute. Same shape
  as `Cldr.Unit.Preference.preferred_units/3`.

* `:alt` is `:informal` or `nil`. Forward-compatible placeholder for
  CLDR's planned alt-keyed preferences (informal-context units);
  accepted but currently has no effect because no `<unitPreference>`
  in the shipped CLDR data carries an `alt` attribute.

### Returns

* `{:ok, units, options}` where `units` is a list of unit name atoms
  and `options` is a keyword list of formatting hints (e.g.,
  `[round_nearest: 1]`).

* `{:error, exception}` if preferences cannot be resolved.

### Examples

    iex> meter = Localize.Unit.new!(1, "meter")
    iex> {:ok, units, _opts} = Localize.Unit.Preference.preferred_units(meter, usage: :person, territory: :US)
    iex> units
    [:inch]

    iex> many_meters = Localize.Unit.new!(10_000, "meter")
    iex> {:ok, units, _opts} = Localize.Unit.Preference.preferred_units(many_meters, usage: :road, territory: :US)
    iex> units
    [:mile]

    iex> warm = Localize.Unit.new!(20, "celsius")
    iex> {:ok, units, _opts} = Localize.Unit.Preference.preferred_units(warm, locale: "de-u-mu-fahrenhe")
    iex> units
    [:fahrenheit]

# `preferred_units!`

```elixir
@spec preferred_units!(Localize.Unit.t(), Keyword.t()) :: [atom()] | no_return()
```

Same as `preferred_units/2` but raises on error.

### Arguments

* `unit` is a `t:Localize.Unit.t/0` struct.

* `options` is a keyword list of options.

### Options

See `preferred_units/2` for the supported options.

### Returns

* A list of unit name atoms.

### Examples

    iex> meter = Localize.Unit.new!(1, "meter")
    iex> Localize.Unit.Preference.preferred_units!(meter, usage: :person, territory: :US)
    [:inch]

    iex> many_meters = Localize.Unit.new!(10_000, "meter")
    iex> Localize.Unit.Preference.preferred_units!(many_meters, usage: :road, territory: :US)
    [:mile]

---

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