accept_language 2.0.8 → 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 +4 -4
- data/LICENSE.md +1 -1
- data/README.md +34 -106
- data/lib/accept_language/matcher.rb +16 -20
- data/lib/accept_language/parser.rb +18 -18
- data/lib/accept_language.rb +14 -28
- metadata +19 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7273e9328183e3dee11fd68a6598d82c67efbb8bab156d6d9b3424d9ed45dcca
|
|
4
|
+
data.tar.gz: ec31e8a4ac07501f1c481e65452f362be2d7669d93eea626977f25c3aca88dc2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 36120af5b03b49ea9dce1d50e5c7915c62bf9b0fa09c1130516090e4e3c882b924035f963ad2dc559fda0e818633b6a3e77aba3e46b25533bc972f5dc23ca729
|
|
7
|
+
data.tar.gz: d11855f60c7a4a35c8f675ea5ffc4b320db5a4b40cc95e57143b3dad3c188580830ae0052ac7e934f5ae4c5f2be582db47b4e85b9513b78b4ec1fc69a97ee850
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
|
@@ -1,148 +1,75 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AcceptLanguage
|
|
2
2
|
|
|
3
|
-
|
|
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
|
[](https://github.com/cyril/accept_language.rb/tags)
|
|
14
6
|
[](https://rubydoc.info/github/cyril/accept_language.rb/main)
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+

|
|
8
|
+

|
|
17
9
|
[](https://github.com/cyril/accept_language.rb/raw/main/LICENSE.md)
|
|
18
10
|
|
|
19
|
-
##
|
|
11
|
+
## Features
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
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:
|
|
38
|
-
|
|
39
|
-
```sh
|
|
40
|
-
bundle install
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Or install it yourself as:
|
|
44
|
-
|
|
45
|
-
```sh
|
|
46
|
-
gem install accept_language
|
|
47
|
-
```
|
|
48
|
-
|
|
49
25
|
## Usage
|
|
50
26
|
|
|
51
|
-
The `Accept Language` library helps web applications serve content in the user's preferred language by parsing the `Accept-Language` HTTP header. This header indicates the user's language preferences and their priority order.
|
|
52
|
-
|
|
53
|
-
### Basic Syntax
|
|
54
|
-
|
|
55
|
-
The library has two main methods:
|
|
56
|
-
|
|
57
|
-
- `AcceptLanguage.parse(header)`: Parses the Accept-Language header
|
|
58
|
-
- `match(*available_languages)`: Matches against the languages your application supports
|
|
59
|
-
|
|
60
27
|
```ruby
|
|
61
|
-
AcceptLanguage.parse("
|
|
28
|
+
AcceptLanguage.parse("en-GB, en;q=0.9").match(:en, :"en-GB")
|
|
29
|
+
# => :"en-GB"
|
|
62
30
|
```
|
|
63
31
|
|
|
64
|
-
###
|
|
32
|
+
### Quality values
|
|
65
33
|
|
|
66
|
-
|
|
34
|
+
Quality values (q-values) indicate preference order from 0 to 1:
|
|
67
35
|
|
|
68
36
|
```ruby
|
|
69
|
-
|
|
70
|
-
# Available: :en and :da
|
|
71
|
-
AcceptLanguage.parse("da").match(:en, :da) # => :da
|
|
72
|
-
|
|
73
|
-
# No match available - returns nil
|
|
74
|
-
AcceptLanguage.parse("da").match(:fr, :en) # => nil
|
|
75
|
-
```
|
|
37
|
+
parser = AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7")
|
|
76
38
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
```ruby
|
|
82
|
-
# Header: "da, en-GB;q=0.8, en;q=0.7"
|
|
83
|
-
# Means:
|
|
84
|
-
# - Danish (da): q=1.0 (highest priority)
|
|
85
|
-
# - British English (en-GB): q=0.8 (second choice)
|
|
86
|
-
# - Generic English (en): q=0.7 (third choice)
|
|
87
|
-
AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7").match(:en, :da) # => :da
|
|
88
|
-
AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7").match(:en, :"en-GB") # => :"en-GB"
|
|
39
|
+
parser.match(:en, :da) # => :da
|
|
40
|
+
parser.match(:en, :"en-GB") # => :"en-GB"
|
|
41
|
+
parser.match(:fr) # => nil
|
|
89
42
|
```
|
|
90
43
|
|
|
91
|
-
|
|
44
|
+
### Language variants
|
|
92
45
|
|
|
93
|
-
|
|
46
|
+
A generic language tag matches its regional variants, but not the reverse:
|
|
94
47
|
|
|
95
48
|
```ruby
|
|
96
|
-
#
|
|
97
|
-
AcceptLanguage.parse("fr-CH").match(:fr)
|
|
98
|
-
|
|
99
|
-
# But generic variants can match specific ones
|
|
100
|
-
AcceptLanguage.parse("fr").match(:"fr-CH") # => :"fr-CH"
|
|
101
|
-
|
|
102
|
-
# Script variants are also supported
|
|
103
|
-
AcceptLanguage.parse("uz-Latn-UZ").match("uz-Latn-UZ") # => "uz-Latn-UZ"
|
|
49
|
+
AcceptLanguage.parse("fr").match(:"fr-CH") # => :"fr-CH"
|
|
50
|
+
AcceptLanguage.parse("fr-CH").match(:fr) # => nil
|
|
104
51
|
```
|
|
105
52
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
The `*` wildcard matches any language, and `q=0` excludes languages:
|
|
109
|
-
|
|
110
|
-
```ruby
|
|
111
|
-
# Accept any language but prefer German
|
|
112
|
-
AcceptLanguage.parse("de-DE, *;q=0.5").match(:fr) # => :fr (matched by wildcard)
|
|
113
|
-
|
|
114
|
-
# Accept any language EXCEPT English
|
|
115
|
-
AcceptLanguage.parse("*, en;q=0").match(:en) # => nil (explicitly excluded)
|
|
116
|
-
AcceptLanguage.parse("*, en;q=0").match(:fr) # => :fr (matched by wildcard)
|
|
117
|
-
```
|
|
53
|
+
### Wildcards and exclusions
|
|
118
54
|
|
|
119
|
-
|
|
55
|
+
The wildcard `*` matches any language. A q-value of 0 explicitly excludes a language:
|
|
120
56
|
|
|
121
57
|
```ruby
|
|
122
|
-
|
|
123
|
-
#
|
|
124
|
-
|
|
125
|
-
# - French: q=0.9 (second choice)
|
|
126
|
-
# - English: q=0.7 (third choice)
|
|
127
|
-
# - Any other language: q=0.5 (lowest priority)
|
|
128
|
-
header = "de-LU, fr;q=0.9, en;q=0.7, *;q=0.5"
|
|
129
|
-
parser = AcceptLanguage.parse(header)
|
|
130
|
-
|
|
131
|
-
parser.match(:de, :"de-LU") # => :"de-LU" (exact match)
|
|
132
|
-
parser.match(:fr, :en) # => :fr (higher q-value)
|
|
133
|
-
parser.match(:es, :it) # => :es (matched by wildcard)
|
|
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
|
|
134
61
|
```
|
|
135
62
|
|
|
136
|
-
### Case
|
|
63
|
+
### Case sensitivity
|
|
137
64
|
|
|
138
|
-
|
|
65
|
+
Matching is case-insensitive but preserves the case of the available language tag:
|
|
139
66
|
|
|
140
67
|
```ruby
|
|
141
68
|
AcceptLanguage.parse("en-GB").match("en-gb") # => "en-gb"
|
|
142
69
|
AcceptLanguage.parse("en-gb").match("en-GB") # => "en-GB"
|
|
143
70
|
```
|
|
144
71
|
|
|
145
|
-
|
|
72
|
+
## Rails integration
|
|
146
73
|
|
|
147
74
|
```ruby
|
|
148
75
|
# app/controllers/application_controller.rb
|
|
@@ -171,15 +98,16 @@ class ApplicationController < ActionController::Base
|
|
|
171
98
|
end
|
|
172
99
|
```
|
|
173
100
|
|
|
174
|
-
##
|
|
101
|
+
## Documentation
|
|
175
102
|
|
|
103
|
+
- [API Documentation](https://rubydoc.info/github/cyril/accept_language.rb/main)
|
|
176
104
|
- [Language negotiation with Ruby](https://dev.to/cyri_/language-negotiation-with-ruby-5166)
|
|
177
105
|
- [Rubyで言語ネゴシエーション](https://qiita.com/cyril/items/45dc233edb7be9d614e7)
|
|
178
106
|
|
|
179
107
|
## Versioning
|
|
180
108
|
|
|
181
|
-
|
|
109
|
+
This library follows [Semantic Versioning 2.0.0](https://semver.org/).
|
|
182
110
|
|
|
183
111
|
## License
|
|
184
112
|
|
|
185
|
-
|
|
113
|
+
Available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -5,19 +5,16 @@ module AcceptLanguage
|
|
|
5
5
|
# the optimal language choice. Handles quality values, wildcards, and language tag matching
|
|
6
6
|
# according to RFC 2616 specifications.
|
|
7
7
|
#
|
|
8
|
-
# @
|
|
9
|
-
#
|
|
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
|
-
#
|
|
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,15 +31,7 @@ module AcceptLanguage
|
|
|
34
31
|
@preferred_langtags = langtags.compact.reverse
|
|
35
32
|
end
|
|
36
33
|
|
|
37
|
-
#
|
|
38
|
-
# Handles priorities based on:
|
|
39
|
-
# 1. Explicit quality values (q-values)
|
|
40
|
-
# 2. Language tag specificity (exact matches preferred over partial matches)
|
|
41
|
-
# 3. Order of preference in the original Accept-Language header
|
|
42
|
-
#
|
|
43
|
-
# @param [Array<String, Symbol>] available_langtags Languages supported by your application
|
|
44
|
-
# @return [String, Symbol, nil] Best matching language or nil if no acceptable match found
|
|
45
|
-
# @raise [ArgumentError] If any language tag is nil
|
|
34
|
+
# @api private
|
|
46
35
|
def call(*available_langtags)
|
|
47
36
|
raise ::ArgumentError, "Language tags cannot be nil" if available_langtags.any?(&:nil?)
|
|
48
37
|
|
|
@@ -72,13 +61,17 @@ module AcceptLanguage
|
|
|
72
61
|
end
|
|
73
62
|
|
|
74
63
|
def find_matching_tag(preferred_tag, available_langtags)
|
|
75
|
-
|
|
64
|
+
pattern = /\A#{::Regexp.escape(preferred_tag)}/i
|
|
65
|
+
available_langtags.find { |tag| tag.match?(pattern) }
|
|
76
66
|
end
|
|
77
67
|
|
|
78
68
|
def any_other_langtag(*available_langtags)
|
|
79
69
|
available_langtags.find do |available_langtag|
|
|
80
70
|
langtags = preferred_langtags - [WILDCARD]
|
|
81
|
-
langtags.none?
|
|
71
|
+
langtags.none? do |tag|
|
|
72
|
+
pattern = /\A#{::Regexp.escape(tag)}/i
|
|
73
|
+
available_langtag.match?(pattern)
|
|
74
|
+
end
|
|
82
75
|
end
|
|
83
76
|
end
|
|
84
77
|
|
|
@@ -91,7 +84,10 @@ module AcceptLanguage
|
|
|
91
84
|
end
|
|
92
85
|
|
|
93
86
|
def unacceptable?(langtag)
|
|
94
|
-
excluded_langtags.any?
|
|
87
|
+
excluded_langtags.any? do |excluded_tag|
|
|
88
|
+
pattern = /\A#{::Regexp.escape(excluded_tag)}/i
|
|
89
|
+
langtag.match?(pattern)
|
|
90
|
+
end
|
|
95
91
|
end
|
|
96
92
|
|
|
97
93
|
def wildcard?(value)
|
|
@@ -8,27 +8,31 @@ module AcceptLanguage
|
|
|
8
8
|
# and handles edge cases like malformed inputs and implicit quality values.
|
|
9
9
|
#
|
|
10
10
|
# @example
|
|
11
|
-
# Parser.new("da, en-GB;q=0.8, en;q=0.7")
|
|
12
|
-
# # =>
|
|
11
|
+
# parser = Parser.new("da, en-GB;q=0.8, en;q=0.7")
|
|
12
|
+
# parser.match(:en, :da) # => :da
|
|
13
13
|
#
|
|
14
|
-
# @see https://tools.ietf.org/html/rfc2616#section-14.4
|
|
14
|
+
# @see https://tools.ietf.org/html/rfc2616#section-14.4
|
|
15
15
|
class Parser
|
|
16
|
+
# @api private
|
|
16
17
|
DEFAULT_QUALITY = "1"
|
|
18
|
+
# @api private
|
|
17
19
|
SEPARATOR = ","
|
|
20
|
+
# @api private
|
|
18
21
|
SPACE = " "
|
|
22
|
+
# @api private
|
|
19
23
|
SUFFIX = ";q="
|
|
20
|
-
|
|
21
|
-
# Validates q-values according to RFC 2616:
|
|
22
|
-
# - Must be between 0 and 1
|
|
23
|
-
# - Can have up to 3 decimal places
|
|
24
|
-
# - Allows both forms: .8 and 0.8
|
|
24
|
+
# @api private
|
|
25
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/
|
|
26
28
|
|
|
29
|
+
# @api private
|
|
30
|
+
# @return [Hash<String, BigDecimal>] Parsed language tags and their quality values
|
|
27
31
|
attr_reader :languages_range
|
|
28
32
|
|
|
29
33
|
# Initializes a new Parser instance by importing and processing the given Accept-Language header field.
|
|
30
34
|
#
|
|
31
|
-
# @param [String]
|
|
35
|
+
# @param field [String] The Accept-Language header field to parse.
|
|
32
36
|
def initialize(field)
|
|
33
37
|
@languages_range = import(field)
|
|
34
38
|
end
|
|
@@ -36,8 +40,9 @@ module AcceptLanguage
|
|
|
36
40
|
# Finds the best matching language from available options based on user preferences.
|
|
37
41
|
# Considers quality values and language tag specificity (e.g., "en-US" vs "en").
|
|
38
42
|
#
|
|
39
|
-
# @param [Array<String, Symbol>]
|
|
43
|
+
# @param available_langtags [Array<String, Symbol>] Languages supported by your application
|
|
40
44
|
# @return [String, Symbol, nil] Best matching language tag or nil if no match found
|
|
45
|
+
#
|
|
41
46
|
# @example Match against specific language options
|
|
42
47
|
# parser.match("en", "fr", "de") # => "en" if English is preferred
|
|
43
48
|
# @example Match with region-specific tags
|
|
@@ -48,13 +53,6 @@ module AcceptLanguage
|
|
|
48
53
|
|
|
49
54
|
private
|
|
50
55
|
|
|
51
|
-
# Processes the Accept-Language header field to extract language tags and their respective quality values.
|
|
52
|
-
#
|
|
53
|
-
# @example
|
|
54
|
-
# import('da, en-GB;q=0.8, en;q=0.7')
|
|
55
|
-
# # => {"da"=>1.0, "en-GB"=>0.8, "en"=>0.7}
|
|
56
|
-
#
|
|
57
|
-
# @return [Hash<String, BigDecimal>] A hash where keys represent language tags and values are their respective quality values.
|
|
58
56
|
def import(field)
|
|
59
57
|
"#{field}".delete(SPACE).split(SEPARATOR).inject({}) do |hash, lang|
|
|
60
58
|
tag, quality = lang.split(SUFFIX)
|
|
@@ -72,7 +70,9 @@ module AcceptLanguage
|
|
|
72
70
|
end
|
|
73
71
|
|
|
74
72
|
def valid_tag?(tag)
|
|
75
|
-
|
|
73
|
+
return false if tag.nil?
|
|
74
|
+
|
|
75
|
+
tag.match?(LANGTAG_PATTERN)
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
end
|
data/lib/accept_language.rb
CHANGED
|
@@ -1,44 +1,30 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# AcceptLanguage is a lightweight library
|
|
4
|
-
#
|
|
5
|
-
# your application's supported languages.
|
|
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
|
-
# # =>
|
|
7
|
+
# @example Basic usage
|
|
8
|
+
# AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7").match(:en, :da)
|
|
9
|
+
# # => :da
|
|
10
10
|
#
|
|
11
|
-
# @example
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
# private
|
|
16
|
-
#
|
|
17
|
-
# def set_locale
|
|
18
|
-
# header = request.env["HTTP_ACCEPT_LANGUAGE"]
|
|
19
|
-
# locale = AcceptLanguage.parse(header).match(*I18n.available_locales)
|
|
20
|
-
# I18n.locale = locale || I18n.default_locale
|
|
21
|
-
# end
|
|
22
|
-
# end
|
|
11
|
+
# @example With regional variants
|
|
12
|
+
# AcceptLanguage.parse("fr-CH, fr;q=0.9").match(:fr, :"fr-CH")
|
|
13
|
+
# # => :"fr-CH"
|
|
23
14
|
#
|
|
24
15
|
# @see https://tools.ietf.org/html/rfc2616#section-14.4
|
|
25
16
|
module AcceptLanguage
|
|
26
|
-
# Parses an Accept-Language header field value
|
|
27
|
-
# user's preferred languages against the languages your application supports.
|
|
28
|
-
# This method accepts a string argument in the format as described in RFC 2616 Section 14.4, and returns
|
|
29
|
-
# a Parser object which responds to the #match method.
|
|
17
|
+
# Parses an Accept-Language header field value.
|
|
30
18
|
#
|
|
31
|
-
# @param field [String]
|
|
19
|
+
# @param field [String] The Accept-Language header field value
|
|
20
|
+
# @return [Parser] A parser object that responds to {Parser#match}
|
|
32
21
|
#
|
|
33
22
|
# @example
|
|
34
|
-
# AcceptLanguage.parse("
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
# @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"
|
|
38
25
|
def self.parse(field)
|
|
39
26
|
Parser.new(field)
|
|
40
27
|
end
|
|
41
28
|
end
|
|
42
29
|
|
|
43
|
-
# Load the Parser class
|
|
44
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
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cyril Kato
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
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
|
|
@@ -35,14 +49,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
35
49
|
requirements:
|
|
36
50
|
- - ">="
|
|
37
51
|
- !ruby/object:Gem::Version
|
|
38
|
-
version: 3.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.
|
|
59
|
+
rubygems_version: 3.4.19
|
|
46
60
|
signing_key:
|
|
47
61
|
specification_version: 4
|
|
48
62
|
summary: "Parser for Accept-Language request HTTP header \U0001F310"
|