Class: Rack::ICU4X::Locale::Negotiator

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/icu4x/locale/negotiator.rb

Overview

Performs script-safe language negotiation using ICU4X’s maximize.

Matches requested locales against available locales, respecting script differences to avoid politically sensitive fallbacks (e.g., zh-TW won’t match zh-CN).

Examples:

locales = %w[en-US en-GB ja].map { |s| ICU4X::Locale.parse(s) }
negotiator = Rack::ICU4X::Locale::Negotiator.new(locales)
negotiator.negotiate(%w[en-AU ja-JP])  # => ["en-US", "ja"]

Instance Method Summary collapse

Constructor Details

#initialize(available_locales) ⇒ Negotiator

Returns a new instance of Negotiator.

Parameters:

  • available_locales (Array<ICU4X::Locale>)

    List of available locales



17
18
19
# File 'lib/rack/icu4x/locale/negotiator.rb', line 17

def initialize(available_locales)
  @available = build_available_index(available_locales)
end

Instance Method Details

#negotiate(requested_locales) {|String| ... } ⇒ Array<String>

Negotiate locales, returning all matches in preference order.

Parameters:

  • requested_locales (Array<String>)

    Requested locale identifiers in preference order

Yields:

  • (String)

    Invalid locale string that could not be parsed

Returns:

  • (Array<String>)

    Matched locale identifiers



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/rack/icu4x/locale/negotiator.rb', line 26

def negotiate(requested_locales)
  matched = []
  remaining = @available.dup

  requested_locales.each do |req_str|
    req_max = maximize_locale(req_str)

    # 1. Exact match (language + script + region)
    if (found = find_exact_match(remaining, req_max))
      matched << found[:original]
      remaining.delete(found)
      next
    end

    # 2. Language + Script match (ignore region)
    #    CRITICAL: Script MUST match to avoid politically sensitive fallbacks
    if (found = find_lang_script_match(remaining, req_max))
      matched << found[:original]
      remaining.delete(found)
    end
  rescue
    yield req_str if block_given?
  end

  matched
end