accept_language 2.0.2 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25f4296b38885118c1d127873d887a138bbfb6615ec0dc3d2db826e14e96e7d7
4
- data.tar.gz: 9f2fac2c3818c94c5b7c7bc6d95655e3fefcb54c5ec5a3ba4ef28d05213fa00f
3
+ metadata.gz: c0ab90b33cf7595d9009aff633cd9bd812a4be94c9192f79b31713c05e1e7306
4
+ data.tar.gz: c5520587db201a89994e3fcc4b4cb9211c1f32fa8361fbf0c900dedbf2b7d5b6
5
5
  SHA512:
6
- metadata.gz: b138c701a374afec0e26b9560570b3f48490a1da1e79f42daa768aa03f038f969f4670e4af57a97c109192410df0b8c66bc39bcc33f7362cc7440be6d243b0e6
7
- data.tar.gz: 4a149d54102620ef411b1c1966f159840e3dec65cf5a2e33e5e045154e1234ee759be0b6ddda4cc8577f778a62e753f96642e49c5fc99e22760e6335a9bfb7aa
6
+ metadata.gz: bfc609d573a6febdf82e00fab5513f18aacc7746ed11f9e4c4200bdb7e82ec65a98764145fb9c0193e9af204b69f9f25842c6cccdfb1f85cfb042bd434f11cfe
7
+ data.tar.gz: 067ae6e1d8e55bce2de8477122bb93006c54582bb63450ce392d7776ebe3e38c8e02cdaf6e6e1aafe46fece34f84c429a0ba74cd95ed2f004e04c5c8a66ddbfe
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
- The MIT License (MIT)
1
+ # The MIT License
2
2
 
3
- Copyright (c) 2019-2022 Cyril Kato
3
+ Copyright (c) 2019-2023 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,22 +1,32 @@
1
1
  # Accept Language 🌐
2
2
 
3
- A tiny library for parsing the `Accept-Language` header from browsers (as defined in [RFC 2616](https://tools.ietf.org/html/rfc2616#section-14.4)).
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.
4
10
 
5
11
  ## Status
6
12
 
7
- [![Version](https://img.shields.io/github/v/tag/cyril/accept_language.rb?label=Version&logo=github)](https://github.com/cyril/accept_language.rb/releases)
13
+ [![Version](https://img.shields.io/github/v/tag/cyril/accept_language.rb?label=Version&logo=github)](https://github.com/cyril/accept_language.rb/tags)
8
14
  [![Yard documentation](https://img.shields.io/badge/Yard-documentation-blue.svg?logo=github)](https://rubydoc.info/github/cyril/accept_language.rb/main)
9
- [![CI](https://github.com/cyril/accept_language.rb/workflows/CI/badge.svg?branch=main)](https://github.com/cyril/accept_language.rb/actions?query=workflow%3Aci+branch%3Amain)
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)
10
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)
11
17
  [![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)
12
18
 
13
19
  ## Why this tool?
14
20
 
15
- - Thread-safe implementation.
16
- - Small algorithm that can handle tricky cases.
17
- - Match strings and symbols ignoring the case.
18
- - Works also well without Rails, Rack, i18n.
19
- - Comes with [BCP 47](https://www.rfc-editor.org/bcp/bcp47.txt) support.
21
+ ## Why Choose Accept Language?
22
+
23
+ There are a myriad of tools out there, so why should you consider Accept Language for your next project? Here's why:
24
+
25
+ - **Thread-Safe**: Multithreading can present unique challenges when dealing with shared resources. Our implementation is designed to be thread-safe, preventing potential concurrency issues.
26
+ - **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.
27
+ - **Case-Insensitive Matching**: In line with the principle of robustness, our tool matches both strings and symbols regardless of case, providing greater flexibility.
28
+ - **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.
29
+ - **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.
20
30
 
21
31
  ## Installation
22
32
 
@@ -29,7 +39,7 @@ gem "accept_language"
29
39
  And then execute:
30
40
 
31
41
  ```sh
32
- bundle
42
+ bundle install
33
43
  ```
34
44
 
35
45
  Or install it yourself as:
@@ -40,28 +50,41 @@ gem install accept_language
40
50
 
41
51
  ## Usage
42
52
 
43
- It's intended to be used in a Web server that supports some level of internationalization (i18n), but can be used anytime an `Accept-Language` header string is available.
44
-
45
- In order to help facilitate better i18n, the lib try to find the intersection of the languages the user prefers and the languages your application supports.
53
+ `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.
46
54
 
47
- Some examples:
55
+ Below are some examples of how you might use the library:
48
56
 
49
57
  ```ruby
50
- AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7").match(:en, :da) # => :da
51
- AcceptLanguage.parse("da, en;q=0.8, ug;q=0.9").match("en-GB", "ug-CN") # => "ug-CN"
52
- AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7").match(:ja) # => nil
53
- AcceptLanguage.parse("fr-CH").match(:fr) # => nil
54
- AcceptLanguage.parse("de, zh;q=0.4, fr;q=0").match(:fr) # => nil
55
- AcceptLanguage.parse("de, zh;q=0.4, *;q=0.5, fr;q=0").match(:ar) # => :ar
56
- AcceptLanguage.parse("uz-latn-uz").match("uz-Latn-UZ") # => "uz-Latn-UZ"
57
- AcceptLanguage.parse("foo;q=0.1").match(:FoO) # => :FoO
58
- AcceptLanguage.parse("foo").match("bar") # => nil
59
- AcceptLanguage.parse("*").match("BaZ") # => "BaZ"
60
- AcceptLanguage.parse("*;q=0").match("foobar") # => nil
61
- AcceptLanguage.parse("en, en;q=0").match("en") # => nil
62
- AcceptLanguage.parse("*, en;q=0").match("en") # => nil
58
+ # The user prefers Danish, then British English, and finally any kind of English.
59
+ # Since your application supports English and Danish, it selects Danish as it's the user's first choice.
60
+ AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7").match(:en, :da) # => :da
61
+
62
+ # The user prefers Danish, then English, and finally Uyghur. Your application supports British English and Chinese Uyghur.
63
+ # Here, the library will return Chinese Uyghur because it's the highest ranked language in the user's list that your application supports.
64
+ AcceptLanguage.parse("da, en;q=0.8, ug;q=0.9").match("en-GB", "ug-CN") # => "ug-CN"
65
+
66
+ # The user prefers Danish, then British English, and finally any kind of English. Your application only supports Japanese.
67
+ # Since none of the user's preferred languages are supported, it returns nil.
68
+ AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7").match(:ja) # => nil
69
+
70
+ # The user only accepts Swiss French, but your application only supports French. Since Swiss French and French are not the same, it returns nil.
71
+ AcceptLanguage.parse("fr-CH").match(:fr) # => nil
72
+
73
+ # The user prefers German, then any language except French. Your application supports French.
74
+ # Even though the user specified a wildcard, they explicitly excluded French. Therefore, it returns nil.
75
+ AcceptLanguage.parse("de, zh;q=0.4, *;q=0.5, fr;q=0").match(:fr) # => nil
76
+
77
+ # The user prefers Uyghur (in Latin script, as used in Uzbekistan). Your application supports this exact variant of Uyghur.
78
+ # Since the user's first choice matches a language your application supports, it returns that language.
79
+ AcceptLanguage.parse("uz-latn-uz").match("uz-Latn-UZ") # => "uz-Latn-UZ"
80
+
81
+ # The user doesn't mind what language they get, but they'd prefer not to have English. Your application supports English.
82
+ # Even though the user specified a wildcard, they explicitly excluded English. Therefore, it returns nil.
83
+ AcceptLanguage.parse("*, en;q=0").match("en") # => nil
63
84
  ```
64
85
 
86
+ 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.
87
+
65
88
  ### Rails integration example
66
89
 
67
90
  ```ruby
@@ -90,6 +113,11 @@ class ApplicationController < ActionController::Base
90
113
  end
91
114
  ```
92
115
 
116
+ ## Read more
117
+
118
+ - [Language negotiation with Ruby](https://dev.to/cyri_/language-negotiation-with-ruby-5166)
119
+ - [Rubyで言語ネゴシエーション](https://qiita.com/cyril/items/45dc233edb7be9d614e7)
120
+
93
121
  ## Versioning
94
122
 
95
123
  __AcceptLanguage__ uses [Semantic Versioning 2.0.0](https://semver.org/)
@@ -1,24 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcceptLanguage
4
- # @note Compare an Accept-Language header value with your application's
5
- # supported languages to find the common languages that could be presented
6
- # to a user.
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.
7
+ #
7
8
  # @example
8
9
  # Matcher.new("da" => 1.0, "en-GB" => 0.8, "en" => 0.7).call(:ug, :kk, :ru, :en) # => :en
9
10
  # Matcher.new("da" => 1.0, "en-GB" => 0.8, "en" => 0.7).call(:fr, :en, :"en-GB") # => :"en-GB"
10
11
  class Matcher
12
+ WILDCARD = "*"
13
+
11
14
  attr_reader :excluded_langtags, :preferred_langtags
12
15
 
13
- # @param [Hash<String, BigDecimal>] languages_range A list of accepted
14
- # languages with their respective qualities.
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.
15
21
  def initialize(**languages_range)
16
- @excluded_langtags = Set[]
22
+ @excluded_langtags = ::Set[]
17
23
  langtags = []
18
24
 
19
25
  languages_range.select do |langtag, quality|
20
26
  if quality.zero?
21
- @excluded_langtags << langtag unless langtag.eql?("*")
27
+ @excluded_langtags << langtag unless wildcard?(langtag)
22
28
  else
23
29
  level = (quality * 1_000).to_i
24
30
  langtags[level] = langtag
@@ -28,16 +34,20 @@ module AcceptLanguage
28
34
  @preferred_langtags = langtags.compact.reverse
29
35
  end
30
36
 
31
- # @param [Array<String, Symbol>] available_langtags The list of available
32
- # languages.
33
- # @example Uyghur, Kazakh, Russian and English languages are available.
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.
34
43
  # call(:ug, :kk, :ru, :en)
35
- # @return [String, Symbol, nil] The language that best matches.
44
+ #
45
+ # @return [String, Symbol, nil] The language that best matches the user's preferences, or nil if there is no match.
36
46
  def call(*available_langtags)
37
47
  available_langtags = drop_unacceptable(*available_langtags)
38
48
 
39
49
  preferred_langtags.each do |preferred_tag|
40
- if preferred_tag.eql?("*")
50
+ if wildcard?(preferred_tag)
41
51
  langtag = any_other_langtag(*available_langtags)
42
52
  return langtag unless langtag.nil?
43
53
  else
@@ -54,7 +64,7 @@ module AcceptLanguage
54
64
 
55
65
  def any_other_langtag(*available_langtags)
56
66
  available_langtags.find do |available_langtag|
57
- langtags = preferred_langtags - ["*"]
67
+ langtags = preferred_langtags - [WILDCARD]
58
68
 
59
69
  langtags.none? do |langtag|
60
70
  available_langtag.match?(/\A#{langtag}/i)
@@ -63,10 +73,10 @@ module AcceptLanguage
63
73
  end
64
74
 
65
75
  def drop_unacceptable(*available_langtags)
66
- available_langtags.inject(Set[]) do |langtags, available_langtag|
76
+ available_langtags.inject(::Set[]) do |langtags, available_langtag|
67
77
  next langtags if unacceptable?(available_langtag)
68
78
 
69
- langtags + Set[available_langtag]
79
+ langtags + ::Set[available_langtag]
70
80
  end
71
81
  end
72
82
 
@@ -75,6 +85,10 @@ module AcceptLanguage
75
85
  langtag.match?(/\A#{excluded_langtag}/i)
76
86
  end
77
87
  end
88
+
89
+ def wildcard?(value)
90
+ value.eql?(WILDCARD)
91
+ end
78
92
  end
79
93
  end
80
94
 
@@ -1,45 +1,62 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "bigdecimal"
4
+
3
5
  module AcceptLanguage
4
- # @note Parser for Accept-Language header fields.
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.
8
+ #
5
9
  # @example
6
- # Parser.new("da, en-GB;q=0.8, en;q=0.7") # => #<AcceptLanguage::Parser:0x00007 @languages_range={"da"=>0.1e1, "en-GB"=>0.8e0, "en"=>0.7e0}>
7
- # @see https://tools.ietf.org/html/rfc2616#section-14.4
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}>
12
+ #
13
+ # @see https://tools.ietf.org/html/rfc2616#section-14.4 for more information on Accept-Language header fields.
8
14
  class Parser
15
+ DEFAULT_QUALITY = BigDecimal("1")
16
+ SEPARATOR = ","
17
+ SPACE = " "
18
+ SUFFIX = ";q="
19
+
9
20
  attr_reader :languages_range
10
21
 
22
+ # Initializes a new Parser instance by importing and processing the given Accept-Language header field.
23
+ #
11
24
  # @param [String] field The Accept-Language header field to parse.
12
- # @see https://tools.ietf.org/html/rfc2616#section-14.4
13
25
  def initialize(field)
14
26
  @languages_range = import(field)
15
27
  end
16
28
 
17
- # @param [Array<String, Symbol>] available_langtags The list of available
18
- # languages.
19
- # @example Uyghur, Kazakh, Russian and English languages are available.
29
+ # Uses the Matcher class to find the best language match from the list of available languages.
30
+ #
31
+ # @param [Array<String, Symbol>] available_langtags An array of language tags that are available for matching.
32
+ #
33
+ # @example When Uyghur, Kazakh, Russian and English languages are available.
20
34
  # match(:ug, :kk, :ru, :en)
21
- # @return [String, Symbol, nil] The language that best matches.
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.
22
37
  def match(*available_langtags)
23
38
  Matcher.new(**languages_range).call(*available_langtags)
24
39
  end
25
40
 
26
41
  private
27
42
 
43
+ # Processes the Accept-Language header field to extract language tags and their respective quality values.
44
+ #
28
45
  # @example
29
- # import('da, en-GB;q=0.8, en;q=0.7') # => {"da"=>0.1e1, "en-GB"=>0.8e0, "en"=>0.7e0}
30
- # @return [Hash<String, BigDecimal>] A list of accepted languages with their
31
- # respective qualities.
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.
32
50
  def import(field)
33
- field.delete(" ").split(",").inject({}) do |hash, lang|
34
- tag, quality = lang.split(/;q=/i)
51
+ field.delete(SPACE).split(SEPARATOR).inject({}) do |hash, lang|
52
+ tag, quality = lang.split(SUFFIX)
35
53
  next hash if tag.nil?
36
54
 
37
- quality = quality.nil? ? BigDecimal("1") : BigDecimal(quality)
55
+ quality = quality.nil? ? DEFAULT_QUALITY : BigDecimal(quality)
38
56
  hash.merge(tag => quality)
39
57
  end
40
58
  end
41
59
  end
42
60
  end
43
61
 
44
- require "bigdecimal"
45
62
  require_relative "matcher"
@@ -1,17 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Tiny library for parsing the Accept-Language header.
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.
6
+ #
4
7
  # @example
5
- # AcceptLanguage.parse("da, en-GB;q=0.8, en;q=0.7") # => #<AcceptLanguage::Parser:0x00007 @languages_range={"da"=>0.1e1, "en-GB"=>0.8e0, "en"=>0.7e0}>
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}>
10
+ #
6
11
  # @see https://tools.ietf.org/html/rfc2616#section-14.4
7
12
  module AcceptLanguage
8
- # @note Parse an Accept-Language header field into a language range.
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
+ #
18
+ # @param field [String] the Accept-Language header field value.
19
+ #
9
20
  # @example
10
- # parse("da, en-GB;q=0.8, en;q=0.7") # => #<AcceptLanguage::Parser:0x00007 @languages_range={"da"=>0.1e1, "en-GB"=>0.8e0, "en"=>0.7e0}>
11
- # @return [#match] a parser that responds to #match.
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.
12
25
  def self.parse(field)
13
26
  Parser.new(field)
14
27
  end
15
28
  end
16
29
 
17
- require_relative "accept_language/parser"
30
+ # Load the Parser class
31
+ require_relative File.join("accept_language", "parser")
metadata CHANGED
@@ -1,155 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: accept_language
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-08 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: r_spec-clone
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rubocop-md
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rubocop-performance
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop-rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: rubocop-rspec
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: rubocop-thread_safety
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: simplecov
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: yard
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
11
+ date: 2023-05-24 00:00:00.000000000 Z
12
+ dependencies: []
153
13
  description: Parses the Accept-Language header from an HTTP request and produces a
154
14
  hash of languages and qualities.
155
15
  email: contact@cyril.email
@@ -175,14 +35,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
175
35
  requirements:
176
36
  - - ">="
177
37
  - !ruby/object:Gem::Version
178
- version: 2.7.5
38
+ version: 3.1.4
179
39
  required_rubygems_version: !ruby/object:Gem::Requirement
180
40
  requirements:
181
41
  - - ">="
182
42
  - !ruby/object:Gem::Version
183
43
  version: '0'
184
44
  requirements: []
185
- rubygems_version: 3.1.6
45
+ rubygems_version: 3.3.26
186
46
  signing_key:
187
47
  specification_version: 4
188
48
  summary: "Parser for Accept-Language request HTTP header \U0001F310"