gossamer/intl/plural_rules

Locale-aware plural-form selection via the JavaScript Intl.PluralRules. Reusing a built PluralRules across many selections is significantly faster than building one per call.

Selection is bound for Float and Int with matching *_range variants returning PluralCategory. BigInt is not supported — Deno, Node, and Bun all throw TypeError on BigInt inputs to Intl.PluralRules.select despite the ES2023 spec allowing them. Convert with big_int.to_int first when the value fits in Int’s safe range.

Types

The configuration for a PluralRules.

pub opaque type Builder

Whether the rules describe cardinal counts (“one apple, two apples”) or ordinal positions (“1st, 2nd, 3rd”). Maps the JavaScript type option.

pub type Kind {
  Cardinal
  Ordinal
}

Constructors

  • Cardinal

    Cardinal counts (the default).

  • Ordinal

    Ordinal positions.

The plural form a number selects under the configured locale and rule type. Mirrors the CLDR plural categories. Not every locale uses every category — English cardinal only distinguishes One and Other, while Arabic uses all six.

pub type PluralCategory {
  Zero
  One
  Two
  Few
  Many
  Other
}

Constructors

  • Zero

    Zero count (e.g., "0 items" in some locales).

  • One

    Singular (e.g., "1 item").

  • Two

    Dual (e.g., Arabic "2 items").

  • Few

    Few (e.g., Russian "2-4 items").

  • Many

    Many (e.g., Polish "5-21 items").

  • Other

    The fallback used when no other category matches.

A configured plural-rules selector that maps a number to its locale-specific plural category.

See Intl.PluralRules on MDN.

pub type PluralRules

The options the runtime resolved for a PluralRules, including the defaults it filled in and the plural_categories the locale actually uses. locale is the BCP 47 tag chosen from the requested priority list; Node and Deno normalize regional tags to the language tag when plural rules don’t differ by region ("en-US" resolves to "en") where Bun keeps the full input tag. The fraction- and significant-digit fields are Some only when the corresponding precision mode is in effect.

pub type ResolvedOptions {
  ResolvedOptions(
    locale: String,
    kind: Kind,
    minimum_integer_digits: Int,
    minimum_fraction_digits: option.Option(Int),
    maximum_fraction_digits: option.Option(Int),
    minimum_significant_digits: option.Option(Int),
    maximum_significant_digits: option.Option(Int),
    plural_categories: List(PluralCategory),
    rounding_increment: Int,
    rounding_mode: intl.RoundingMode,
    rounding_priority: intl.RoundingPriority,
    trailing_zero_display: intl.TrailingZeroDisplay,
  )
}

Constructors

Values

pub fn build(builder: Builder) -> Result(PluralRules, Nil)

Constructs a PluralRules from the configured builder. Returns Error(Nil) if any locale tag is structurally invalid, if a digit-count option is outside its allowed range, or if with_rounding_increment is set to an unsupported value.

pub fn new(locales: List(String)) -> Builder

Creates a Builder for the given locale priority list. The runtime picks the first locale it supports; pass an empty list to use the runtime’s default locale.

pub fn resolved_options(rules: PluralRules) -> ResolvedOptions

The full configuration the runtime resolved from the builder, including the plural categories the locale uses.

pub fn select_float(
  rules: PluralRules,
  value: Float,
) -> PluralCategory

Selects the PluralCategory for a Float value.

pub fn select_float_range(
  rules: PluralRules,
  from start: Float,
  to end: Float,
) -> PluralCategory

Selects the PluralCategory for a Float range from start to end. Passing end < start selects a category for the reversed range without erroring.

pub fn select_int(
  rules: PluralRules,
  value: Int,
) -> PluralCategory

Selects the PluralCategory for an Int value.

pub fn select_int_range(
  rules: PluralRules,
  from start: Int,
  to end: Int,
) -> PluralCategory

Selects the PluralCategory for an Int range from start to end. Passing end < start selects a category for the reversed range without erroring.

pub fn supported_locales_of(
  locales: List(String),
) -> Result(List(String), Nil)

Filters locales to those the runtime supports for plural-rules selection, preserving the input order. Returns Error(Nil) if any locale tag is structurally malformed.

pub fn with_kind(builder: Builder, kind: Kind) -> Builder

Sets whether the rules describe cardinal counts or ordinal positions.

pub fn with_locale_matcher(
  builder: Builder,
  locale_matcher: intl.LocaleMatcher,
) -> Builder

Sets the locale-matching algorithm used to pick a locale from the priority list.

pub fn with_maximum_fraction_digits(
  builder: Builder,
  maximum_fraction_digits: Int,
) -> Builder

Sets the maximum number of fraction digits.

pub fn with_maximum_significant_digits(
  builder: Builder,
  maximum_significant_digits: Int,
) -> Builder

Sets the maximum number of significant digits.

pub fn with_minimum_fraction_digits(
  builder: Builder,
  minimum_fraction_digits: Int,
) -> Builder

Sets the minimum number of fraction digits.

pub fn with_minimum_integer_digits(
  builder: Builder,
  minimum_integer_digits: Int,
) -> Builder

Sets the minimum number of integer digits. Values below the minimum are zero-padded for plural-rule selection purposes.

pub fn with_minimum_significant_digits(
  builder: Builder,
  minimum_significant_digits: Int,
) -> Builder

Sets the minimum number of significant digits.

pub fn with_rounding_increment(
  builder: Builder,
  rounding_increment: Int,
) -> Builder

Sets the rounding increment — the value is rounded to the nearest multiple of this number before plural-rule selection. Valid values are 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, and 5000; other values cause build to return Error(Nil).

pub fn with_rounding_mode(
  builder: Builder,
  rounding_mode: intl.RoundingMode,
) -> Builder

Sets the rounding strategy applied when the formatter discards digits past the configured precision.

pub fn with_rounding_priority(
  builder: Builder,
  rounding_priority: intl.RoundingPriority,
) -> Builder

Sets how rounding interacts when both significant-digit and fraction-digit options are set.

pub fn with_trailing_zero_display(
  builder: Builder,
  trailing_zero_display: intl.TrailingZeroDisplay,
) -> Builder

Sets whether trailing fraction zeros are stripped from integer values prior to plural-rule selection.

Search Document