accept_language 2.0.7 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48e16c31c0c78f967fd5f06f753e83088342a4deafaf149f3de8e95f4dbece93
4
- data.tar.gz: 4c62d54bea6c53797fea29ba73211bfb576fb34bc38c16f0c4fd941ce806bb9c
3
+ metadata.gz: 7273e9328183e3dee11fd68a6598d82c67efbb8bab156d6d9b3424d9ed45dcca
4
+ data.tar.gz: ec31e8a4ac07501f1c481e65452f362be2d7669d93eea626977f25c3aca88dc2
5
5
  SHA512:
6
- metadata.gz: 4476afd57f2d399c7d588b2354de0c95b0cdbce0c3d3b0c3147950f61a6e41b66497bbe8bc076d80cb0e3ecbe208692f1496c9d0fa3e83c89a5ff747c78172d2
7
- data.tar.gz: 65fe33bd3a1d9f6f9ad32ce94f19d3139683e019fd617fbfc36c66b3af2fca0be7c16d70497568f709f54605f6d55a88a465b4f23c4a7a4978b94201bebb7393
6
+ metadata.gz: 36120af5b03b49ea9dce1d50e5c7915c62bf9b0fa09c1130516090e4e3c882b924035f963ad2dc559fda0e818633b6a3e77aba3e46b25533bc972f5dc23ca729
7
+ data.tar.gz: d11855f60c7a4a35c8f675ea5ffc4b320db5a4b40cc95e57143b3dad3c188580830ae0052ac7e934f5ae4c5f2be582db47b4e85b9513b78b4ec1fc69a97ee850
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # The MIT License
2
2
 
3
- Copyright (c) 2019-2024 Cyril Kato
3
+ Copyright (c) 2019-2026 Cyril Kato
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,89 +1,75 @@
1
- # Accept Language 🌐
1
+ # AcceptLanguage
2
2
 
3
- Web applications often need to cater to users from around the world. One of the ways they can provide a better user experience is by presenting the content in the user's preferred language. This is where the `Accept-Language` HTTP header comes into play. Sent by the client (usually a web browser), this header tells the server the list of languages the user understands, and the user's preference order.
4
-
5
- Parsing the `Accept-Language` header can be complex due to its flexible format defined in [RFC 2616](https://tools.ietf.org/html/rfc2616#section-14.4). For instance, it can specify languages, countries, and scripts with varying degrees of preference (quality values).
6
-
7
- `Accept Language` is a lightweight, thread-safe Ruby library designed to parse the `Accept-Language` header, making it easier for your application to determine the best language to respond with. It calculates the intersection of the languages the user prefers and the languages your application supports, handling all the complexity of quality values and wildcards.
8
-
9
- Whether you're building a multilingual web application or just trying to make your service more accessible to users worldwide, `Accept Language` offers a reliable, simple solution.
10
-
11
- ## Status
3
+ A lightweight, thread-safe Ruby library for parsing `Accept-Language` HTTP headers as defined in [RFC 2616](https://tools.ietf.org/html/rfc2616#section-14.4).
12
4
 
13
5
  [![Version](https://img.shields.io/github/v/tag/cyril/accept_language.rb?label=Version&logo=github)](https://github.com/cyril/accept_language.rb/tags)
14
6
  [![Yard documentation](https://img.shields.io/badge/Yard-documentation-blue.svg?logo=github)](https://rubydoc.info/github/cyril/accept_language.rb/main)
15
- [![Ruby](https://github.com/cyril/accept_language.rb/workflows/Ruby/badge.svg?branch=main)](https://github.com/cyril/accept_language.rb/actions?query=workflow%3Aruby+branch%3Amain)
16
- [![RuboCop](https://github.com/cyril/accept_language.rb/workflows/RuboCop/badge.svg?branch=main)](https://github.com/cyril/accept_language.rb/actions?query=workflow%3Arubocop+branch%3Amain)
7
+ ![Ruby](https://github.com/cyril/accept_language.rb/actions/workflows/ruby.yml/badge.svg?branch=main)
8
+ ![RuboCop](https://github.com/cyril/accept_language.rb/actions/workflows/rubocop.yml/badge.svg?branch=main)
17
9
  [![License](https://img.shields.io/github/license/cyril/accept_language.rb?label=License&logo=github)](https://github.com/cyril/accept_language.rb/raw/main/LICENSE.md)
18
10
 
19
- ## Why Choose Accept Language?
20
-
21
- There are a myriad of tools out there, so why should you consider Accept Language for your next project? Here's why:
11
+ ## Features
22
12
 
23
- - **Thread-Safe**: Multithreading can present unique challenges when dealing with shared resources. Our implementation is designed to be thread-safe, preventing potential concurrency issues.
24
- - **Compact and Robust**: Despite being small in size, Accept Language can handle even the trickiest cases with grace, ensuring you have a reliable tool at your disposal.
25
- - **Case-Insensitive Matching**: In line with the principle of robustness, our tool matches both strings and symbols regardless of case, providing greater flexibility.
26
- - **Independent of Framework**: While many tools require Rails, Rack, or i18n to function, Accept Language stands on its own. It works perfectly well without these dependencies, increasing its adaptability.
27
- - **BCP 47 Support**: BCP 47 defines a standard for language tags. This is crucial for specifying languages unambiguously. Accept Language complies with this standard, ensuring accurate language identification.
13
+ - Thread-safe
14
+ - No framework dependencies
15
+ - Case-insensitive matching
16
+ - BCP 47 language tag support
17
+ - Wildcard and exclusion handling
28
18
 
29
19
  ## Installation
30
20
 
31
- Add this line to your application's Gemfile:
32
-
33
21
  ```ruby
34
22
  gem "accept_language"
35
23
  ```
36
24
 
37
- And then execute:
25
+ ## Usage
38
26
 
39
- ```sh
40
- bundle install
27
+ ```ruby
28
+ AcceptLanguage.parse("en-GB, en;q=0.9").match(:en, :"en-GB")
29
+ # => :"en-GB"
41
30
  ```
42
31
 
43
- Or install it yourself as:
32
+ ### Quality values
44
33
 
45
- ```sh
46
- gem install accept_language
47
- ```
34
+ Quality values (q-values) indicate preference order from 0 to 1:
48
35
 
49
- ## Usage
36
+ ```ruby
37
+ parser = AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7")
50
38
 
51
- `Accept Language` library is primarily designed to assist web servers in serving multilingual content based on user preferences expressed in the `Accept-Language` header. This library finds the best matching language from the available languages your application supports and the languages the user prefers.
39
+ parser.match(:en, :da) # => :da
40
+ parser.match(:en, :"en-GB") # => :"en-GB"
41
+ parser.match(:fr) # => nil
42
+ ```
52
43
 
53
- Below are some examples of how you might use the library:
44
+ ### Language variants
45
+
46
+ A generic language tag matches its regional variants, but not the reverse:
54
47
 
55
48
  ```ruby
56
- # The user prefers Danish, then British English, and finally any kind of English.
57
- # Since your application supports English and Danish, it selects Danish as it's the user's first choice.
58
- AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7").match(:en, :da) # => :da
49
+ AcceptLanguage.parse("fr").match(:"fr-CH") # => :"fr-CH"
50
+ AcceptLanguage.parse("fr-CH").match(:fr) # => nil
51
+ ```
59
52
 
60
- # The user prefers Danish, then English, and finally Uyghur. Your application supports British English and Chinese Uyghur.
61
- # Here, the library will return Chinese Uyghur because it's the highest ranked language in the user's list that your application supports.
62
- AcceptLanguage.parse("da, en;q=0.8, ug;q=0.9").match("en-GB", "ug-CN") # => "ug-CN"
53
+ ### Wildcards and exclusions
63
54
 
64
- # The user prefers Danish, then British English, and finally any kind of English. Your application only supports Japanese.
65
- # Since none of the user's preferred languages are supported, it returns nil.
66
- AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7").match(:ja) # => nil
55
+ The wildcard `*` matches any language. A q-value of 0 explicitly excludes a language:
67
56
 
68
- # The user only accepts Swiss French, but your application only supports French. Since Swiss French and French are not the same, it returns nil.
69
- AcceptLanguage.parse("fr-CH").match(:fr) # => nil
57
+ ```ruby
58
+ AcceptLanguage.parse("de-DE, *;q=0.5").match(:fr) # => :fr
59
+ AcceptLanguage.parse("*, en;q=0").match(:en) # => nil
60
+ AcceptLanguage.parse("*, en;q=0").match(:fr) # => :fr
61
+ ```
70
62
 
71
- # The user prefers German, then any language except French. Your application supports French.
72
- # Even though the user specified a wildcard, they explicitly excluded French. Therefore, it returns nil.
73
- AcceptLanguage.parse("de, zh;q=0.4, *;q=0.5, fr;q=0").match(:fr) # => nil
63
+ ### Case sensitivity
74
64
 
75
- # The user prefers Uyghur (in Latin script, as used in Uzbekistan). Your application supports this exact variant of Uyghur.
76
- # Since the user's first choice matches a language your application supports, it returns that language.
77
- AcceptLanguage.parse("uz-latn-uz").match("uz-Latn-UZ") # => "uz-Latn-UZ"
65
+ Matching is case-insensitive but preserves the case of the available language tag:
78
66
 
79
- # The user doesn't mind what language they get, but they'd prefer not to have English. Your application supports English.
80
- # Even though the user specified a wildcard, they explicitly excluded English. Therefore, it returns nil.
81
- AcceptLanguage.parse("*, en;q=0").match("en") # => nil
67
+ ```ruby
68
+ AcceptLanguage.parse("en-GB").match("en-gb") # => "en-gb"
69
+ AcceptLanguage.parse("en-gb").match("en-GB") # => "en-GB"
82
70
  ```
83
71
 
84
- These examples show the flexibility and power of `Accept Language`. By giving your application a deep understanding of the user's language preferences, `Accept Language` can significantly improve user satisfaction and engagement with your application.
85
-
86
- ### Rails integration example
72
+ ## Rails integration
87
73
 
88
74
  ```ruby
89
75
  # app/controllers/application_controller.rb
@@ -95,6 +81,7 @@ class ApplicationController < ActionController::Base
95
81
  end
96
82
 
97
83
  def best_locale_from_request
84
+ # HTTP_ACCEPT_LANGUAGE is the standardized key for the Accept-Language header in Rack/Rails
98
85
  return I18n.default_locale unless request.headers.key?("HTTP_ACCEPT_LANGUAGE")
99
86
 
100
87
  string = request.headers.fetch("HTTP_ACCEPT_LANGUAGE")
@@ -111,15 +98,16 @@ class ApplicationController < ActionController::Base
111
98
  end
112
99
  ```
113
100
 
114
- ## Read more
101
+ ## Documentation
115
102
 
103
+ - [API Documentation](https://rubydoc.info/github/cyril/accept_language.rb/main)
116
104
  - [Language negotiation with Ruby](https://dev.to/cyri_/language-negotiation-with-ruby-5166)
117
105
  - [Rubyで言語ネゴシエーション](https://qiita.com/cyril/items/45dc233edb7be9d614e7)
118
106
 
119
107
  ## Versioning
120
108
 
121
- __AcceptLanguage__ uses [Semantic Versioning 2.0.0](https://semver.org/)
109
+ This library follows [Semantic Versioning 2.0.0](https://semver.org/).
122
110
 
123
111
  ## License
124
112
 
125
- The [gem](https://rubygems.org/gems/accept_language) is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
113
+ Available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -1,23 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcceptLanguage
4
- # A utility class that provides functionality to match the Accept-Language header value
5
- # against the languages supported by your application. This helps in identifying the most
6
- # suitable languages to present to the user based on their preferences.
4
+ # Matches Accept-Language header values against application-supported languages to determine
5
+ # the optimal language choice. Handles quality values, wildcards, and language tag matching
6
+ # according to RFC 2616 specifications.
7
7
  #
8
- # @example
9
- # Matcher.new("da" => 1.0, "en-GB" => 0.8, "en" => 0.7).call(:ug, :kk, :ru, :en) # => :en
10
- # Matcher.new("da" => 1.0, "en-GB" => 0.8, "en" => 0.7).call(:fr, :en, :"en-GB") # => :"en-GB"
8
+ # @api private
9
+ # @note This class is intended for internal use by {Parser} and should not be instantiated directly.
11
10
  class Matcher
11
+ # @api private
12
12
  WILDCARD = "*"
13
13
 
14
+ # @api private
14
15
  attr_reader :excluded_langtags, :preferred_langtags
15
16
 
16
- # Initialize a new Matcher object with the languages_range parameter representing the user's
17
- # preferred languages and their respective quality values.
18
- #
19
- # @param [Hash<String, BigDecimal>] languages_range A hash where keys represent languages and
20
- # values are the quality of preference for each language. A value of zero means the language is not acceptable.
17
+ # @api private
21
18
  def initialize(**languages_range)
22
19
  @excluded_langtags = ::Set[]
23
20
  langtags = []
@@ -34,40 +31,46 @@ module AcceptLanguage
34
31
  @preferred_langtags = langtags.compact.reverse
35
32
  end
36
33
 
37
- # Matches the user's preferred languages against the available languages of your application.
38
- # It prioritizes higher quality values and returns the most suitable match.
39
- #
40
- # @param [Array<String, Symbol>] available_langtags An array representing the languages available in your application.
41
- #
42
- # @example When Uyghur, Kazakh, Russian and English languages are available.
43
- # call(:ug, :kk, :ru, :en)
44
- #
45
- # @return [String, Symbol, nil] The language that best matches the user's preferences, or nil if there is no match.
34
+ # @api private
46
35
  def call(*available_langtags)
47
- available_langtags = drop_unacceptable(*available_langtags)
36
+ raise ::ArgumentError, "Language tags cannot be nil" if available_langtags.any?(&:nil?)
48
37
 
38
+ filtered_tags = drop_unacceptable(*available_langtags)
39
+ return nil if filtered_tags.empty?
40
+
41
+ find_best_match(filtered_tags)
42
+ end
43
+
44
+ private
45
+
46
+ def find_best_match(available_langtags)
49
47
  preferred_langtags.each do |preferred_tag|
50
- if wildcard?(preferred_tag)
51
- langtag = any_other_langtag(*available_langtags)
52
- return langtag unless langtag.nil?
53
- else
54
- available_langtags.each do |available_langtag|
55
- return available_langtag if available_langtag.match?(/\A#{preferred_tag}/i)
56
- end
57
- end
48
+ match = match_langtag(preferred_tag, available_langtags)
49
+ return match if match
58
50
  end
59
51
 
60
52
  nil
61
53
  end
62
54
 
63
- private
55
+ def match_langtag(preferred_tag, available_langtags)
56
+ if wildcard?(preferred_tag)
57
+ any_other_langtag(*available_langtags)
58
+ else
59
+ find_matching_tag(preferred_tag, available_langtags)
60
+ end
61
+ end
62
+
63
+ def find_matching_tag(preferred_tag, available_langtags)
64
+ pattern = /\A#{::Regexp.escape(preferred_tag)}/i
65
+ available_langtags.find { |tag| tag.match?(pattern) }
66
+ end
64
67
 
65
68
  def any_other_langtag(*available_langtags)
66
69
  available_langtags.find do |available_langtag|
67
70
  langtags = preferred_langtags - [WILDCARD]
68
-
69
- langtags.none? do |langtag|
70
- available_langtag.match?(/\A#{langtag}/i)
71
+ langtags.none? do |tag|
72
+ pattern = /\A#{::Regexp.escape(tag)}/i
73
+ available_langtag.match?(pattern)
71
74
  end
72
75
  end
73
76
  end
@@ -81,8 +84,9 @@ module AcceptLanguage
81
84
  end
82
85
 
83
86
  def unacceptable?(langtag)
84
- excluded_langtags.any? do |excluded_langtag|
85
- langtag.match?(/\A#{excluded_langtag}/i)
87
+ excluded_langtags.any? do |excluded_tag|
88
+ pattern = /\A#{::Regexp.escape(excluded_tag)}/i
89
+ langtag.match?(pattern)
86
90
  end
87
91
  end
88
92
 
@@ -3,59 +3,77 @@
3
3
  require "bigdecimal"
4
4
 
5
5
  module AcceptLanguage
6
- # Parser is a utility class responsible for parsing Accept-Language header fields.
7
- # It processes the field to extract language tags and their respective quality values.
6
+ # Parses Accept-Language header fields into structured data, extracting language tags
7
+ # and their quality values (q-values). Validates input according to RFC 2616 specifications
8
+ # and handles edge cases like malformed inputs and implicit quality values.
8
9
  #
9
10
  # @example
10
- # Parser.new("da, en-GB;q=0.8, en;q=0.7")
11
- # # => #<AcceptLanguage::Parser:0x00007 @languages_range={"da"=>1.0, "en-GB"=>0.8, "en"=>0.7}>
11
+ # parser = Parser.new("da, en-GB;q=0.8, en;q=0.7")
12
+ # parser.match(:en, :da) # => :da
12
13
  #
13
- # @see https://tools.ietf.org/html/rfc2616#section-14.4 for more information on Accept-Language header fields.
14
+ # @see https://tools.ietf.org/html/rfc2616#section-14.4
14
15
  class Parser
15
- DEFAULT_QUALITY = BigDecimal("1")
16
+ # @api private
17
+ DEFAULT_QUALITY = "1"
18
+ # @api private
16
19
  SEPARATOR = ","
20
+ # @api private
17
21
  SPACE = " "
22
+ # @api private
18
23
  SUFFIX = ";q="
24
+ # @api private
25
+ QVALUE_PATTERN = /\A(?:0(?:\.[0-9]{1,3})?|1(?:\.0{1,3})?|\.[0-9]{1,3})\z/
26
+ # @api private
27
+ LANGTAG_PATTERN = /\A(?:\*|[a-zA-Z]{1,8}(?:-[a-zA-Z0-9]{1,8})*)\z/
19
28
 
29
+ # @api private
30
+ # @return [Hash<String, BigDecimal>] Parsed language tags and their quality values
20
31
  attr_reader :languages_range
21
32
 
22
33
  # Initializes a new Parser instance by importing and processing the given Accept-Language header field.
23
34
  #
24
- # @param [String] field The Accept-Language header field to parse.
35
+ # @param field [String] The Accept-Language header field to parse.
25
36
  def initialize(field)
26
37
  @languages_range = import(field)
27
38
  end
28
39
 
29
- # Uses the Matcher class to find the best language match from the list of available languages.
40
+ # Finds the best matching language from available options based on user preferences.
41
+ # Considers quality values and language tag specificity (e.g., "en-US" vs "en").
30
42
  #
31
- # @param [Array<String, Symbol>] available_langtags An array of language tags that are available for matching.
43
+ # @param available_langtags [Array<String, Symbol>] Languages supported by your application
44
+ # @return [String, Symbol, nil] Best matching language tag or nil if no match found
32
45
  #
33
- # @example When Uyghur, Kazakh, Russian and English languages are available.
34
- # match(:ug, :kk, :ru, :en)
35
- #
36
- # @return [String, Symbol, nil] The language tag that best matches the parsed languages from the Accept-Language header, or nil if no match found.
46
+ # @example Match against specific language options
47
+ # parser.match("en", "fr", "de") # => "en" if English is preferred
48
+ # @example Match with region-specific tags
49
+ # parser.match("en-US", "en-GB", "fr") # => "en-GB" if British English is preferred
37
50
  def match(*available_langtags)
38
51
  Matcher.new(**languages_range).call(*available_langtags)
39
52
  end
40
53
 
41
54
  private
42
55
 
43
- # Processes the Accept-Language header field to extract language tags and their respective quality values.
44
- #
45
- # @example
46
- # import('da, en-GB;q=0.8, en;q=0.7')
47
- # # => {"da"=>1.0, "en-GB"=>0.8, "en"=>0.7}
48
- #
49
- # @return [Hash<String, BigDecimal>] A hash where keys represent language tags and values are their respective quality values.
50
56
  def import(field)
51
57
  "#{field}".delete(SPACE).split(SEPARATOR).inject({}) do |hash, lang|
52
58
  tag, quality = lang.split(SUFFIX)
53
- next hash if tag.nil?
59
+ next hash unless valid_tag?(tag)
54
60
 
55
- quality = quality.nil? ? DEFAULT_QUALITY : BigDecimal(quality)
56
- hash.merge(tag => quality)
61
+ quality = DEFAULT_QUALITY if quality.nil?
62
+ next hash unless valid_quality?(quality)
63
+
64
+ hash.merge(tag => BigDecimal(quality))
57
65
  end
58
66
  end
67
+
68
+ def valid_quality?(quality)
69
+ quality.match?(QVALUE_PATTERN)
70
+ end
71
+
72
+ def valid_tag?(tag)
73
+ return false if tag.nil?
74
+
75
+ tag.match?(LANGTAG_PATTERN)
76
+ end
59
77
  end
60
78
  end
61
79
 
@@ -1,31 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This module provides a tiny library for parsing the Accept-Language header as specified in RFC 2616.
4
- # It transforms the Accept-Language header field into a language range, providing a flexible way to determine
5
- # user's language preferences and match them with the available languages in your application.
3
+ # AcceptLanguage is a lightweight library for parsing Accept-Language HTTP headers
4
+ # as defined in RFC 2616. It determines user language preferences and matches them
5
+ # against your application's supported languages.
6
6
  #
7
- # @example
8
- # AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7")
9
- # # => #<AcceptLanguage::Parser:0x00007 @languages_range={"da"=>1.0, "en-GB"=>0.8, "en"=>0.7}>
7
+ # @example Basic usage
8
+ # AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7").match(:en, :da)
9
+ # # => :da
10
+ #
11
+ # @example With regional variants
12
+ # AcceptLanguage.parse("fr-CH, fr;q=0.9").match(:fr, :"fr-CH")
13
+ # # => :"fr-CH"
10
14
  #
11
15
  # @see https://tools.ietf.org/html/rfc2616#section-14.4
12
16
  module AcceptLanguage
13
- # Parses an Accept-Language header field value into a Parser object, which can then be used to match
14
- # user's preferred languages against the languages your application supports.
15
- # This method accepts a string argument in the format as described in RFC 2616 Section 14.4, and returns
16
- # a Parser object which responds to the #match method.
17
+ # Parses an Accept-Language header field value.
17
18
  #
18
- # @param field [String] the Accept-Language header field value.
19
+ # @param field [String] The Accept-Language header field value
20
+ # @return [Parser] A parser object that responds to {Parser#match}
19
21
  #
20
22
  # @example
21
- # AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7")
22
- # # => #<AcceptLanguage::Parser:0x00007 @languages_range={"da"=>1.0, "en-GB"=>0.8, "en"=>0.7}>
23
- #
24
- # @return [Parser] a Parser object that responds to #match method.
23
+ # parser = AcceptLanguage.parse("en-GB, en;q=0.9")
24
+ # parser.match(:en, :"en-GB") # => :"en-GB"
25
25
  def self.parse(field)
26
26
  Parser.new(field)
27
27
  end
28
28
  end
29
29
 
30
- # Load the Parser class
31
30
  require_relative File.join("accept_language", "parser")
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: accept_language
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-21 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2026-01-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bigdecimal
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  description: Parses the Accept-Language header from an HTTP request and produces a
14
28
  hash of languages and qualities.
15
29
  email: contact@cyril.email
@@ -27,7 +41,7 @@ licenses:
27
41
  - MIT
28
42
  metadata:
29
43
  rubygems_mfa_required: 'true'
30
- post_install_message:
44
+ post_install_message:
31
45
  rdoc_options: []
32
46
  require_paths:
33
47
  - lib
@@ -35,15 +49,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
35
49
  requirements:
36
50
  - - ">="
37
51
  - !ruby/object:Gem::Version
38
- version: 3.2.2
52
+ version: 3.2.0
39
53
  required_rubygems_version: !ruby/object:Gem::Requirement
40
54
  requirements:
41
55
  - - ">="
42
56
  - !ruby/object:Gem::Version
43
57
  version: '0'
44
58
  requirements: []
45
- rubygems_version: 3.4.22
46
- signing_key:
59
+ rubygems_version: 3.4.19
60
+ signing_key:
47
61
  specification_version: 4
48
62
  summary: "Parser for Accept-Language request HTTP header \U0001F310"
49
63
  test_files: []