mirror of
https://gitea.invidious.io/iv-org/shard-athena-negotiation.git
synced 2024-08-15 00:53:23 +00:00
Make use of generics instead of a method
Allows Crystal to more accurately know the return type of `ordered_elements` Add example of `ordered_elements` usage
This commit is contained in:
parent
83eda1298c
commit
2c40931550
6 changed files with 28 additions and 32 deletions
|
@ -112,6 +112,8 @@ struct NegotiatorTest < NegotiatorTestCase
|
||||||
def test_ordered_elements(header : String, expected : Indexable(String)) : Nil
|
def test_ordered_elements(header : String, expected : Indexable(String)) : Nil
|
||||||
elements = @negotiator.ordered_elements header
|
elements = @negotiator.ordered_elements header
|
||||||
|
|
||||||
|
elements.should be_a Array(ANG::Accept)
|
||||||
|
|
||||||
expected.each_with_index do |element, idx|
|
expected.each_with_index do |element, idx|
|
||||||
elements[idx].should be_a ANG::Accept
|
elements[idx].should be_a ANG::Accept
|
||||||
element.should eq elements[idx].header
|
element.should eq elements[idx].header
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base negotiator type. Implements logic common to all negotiators.
|
# Base negotiator type. Implements logic common to all negotiators.
|
||||||
abstract class Athena::Negotiation::AbstractNegotiator
|
abstract class Athena::Negotiation::AbstractNegotiator(HeaderType)
|
||||||
private record OrderKey, quality : Float32, index : Int32, value : String do
|
private record OrderKey, quality : Float32, index : Int32, value : String do
|
||||||
include Comparable(self)
|
include Comparable(self)
|
||||||
|
|
||||||
|
@ -9,24 +9,22 @@ abstract class Athena::Negotiation::AbstractNegotiator
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private abstract def create_header(header : String) : ANG::BaseAccept
|
# Returns the best `HeaderType` type based on the provided *header* value and *priorities*.
|
||||||
|
|
||||||
# Returns the best `ANG::BaseAccept` type based on the provided *header* value and *priorities*.
|
|
||||||
#
|
#
|
||||||
# See `Athena::Negotiation` for examples.
|
# See `Athena::Negotiation` for examples.
|
||||||
def best(header : String, priorities : Indexable(String), strict : Bool = false) : ANG::BaseAccept?
|
def best(header : String, priorities : Indexable(String), strict : Bool = false) : HeaderType?
|
||||||
raise ArgumentError.new "priorities should not be empty." if priorities.empty?
|
raise ArgumentError.new "priorities should not be empty." if priorities.empty?
|
||||||
raise ArgumentError.new "The header string should not be empty." if header.blank?
|
raise ArgumentError.new "The header string should not be empty." if header.blank?
|
||||||
|
|
||||||
accepted_headers = Array(ANG::BaseAccept).new
|
accepted_headers = Array(HeaderType).new
|
||||||
|
|
||||||
self.parse_header(header) do |h|
|
self.parse_header(header) do |h|
|
||||||
accepted_headers << self.create_header h
|
accepted_headers << HeaderType.new h
|
||||||
rescue ex
|
rescue ex
|
||||||
raise ex if strict
|
raise ex if strict
|
||||||
end
|
end
|
||||||
|
|
||||||
accepted_priorties = priorities.map &->create_header(String)
|
accepted_priorties = priorities.map { |p| HeaderType.new p }
|
||||||
|
|
||||||
matches = self.find_matches accepted_headers, accepted_priorties
|
matches = self.find_matches accepted_headers, accepted_priorties
|
||||||
|
|
||||||
|
@ -41,18 +39,28 @@ abstract class Athena::Negotiation::AbstractNegotiator
|
||||||
match.nil? ? nil : accepted_priorties[match.index]
|
match.nil? ? nil : accepted_priorties[match.index]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an array of `ANG::BaseAccept` types that the provided *header* allows, ordered so that the `#best` match is first.
|
# Returns an array of `HeaderType` types that the provided *header* allows, ordered so that the `#best` match is first.
|
||||||
#
|
#
|
||||||
# See `Athena::Negotiation` for examples.
|
# ```
|
||||||
def ordered_elements(header : String) : Array(ANG::BaseAccept)
|
# header = "text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5"
|
||||||
|
#
|
||||||
|
# ordered_elements = ANG.negotiator.ordered_elements header
|
||||||
|
#
|
||||||
|
# ordered_elements[0].media_range # => "text/html"
|
||||||
|
# ordered_elements[1].media_range # => "text/html"
|
||||||
|
# ordered_elements[2].media_range # => "*/*"
|
||||||
|
# ordered_elements[3].media_range # => "text/html"
|
||||||
|
# ordered_elements[4].media_range # => "text/*"
|
||||||
|
# ```
|
||||||
|
def ordered_elements(header : String) : Array(HeaderType)
|
||||||
raise ArgumentError.new "The header string should not be empty." if header.blank?
|
raise ArgumentError.new "The header string should not be empty." if header.blank?
|
||||||
|
|
||||||
elements = Array(ANG::BaseAccept).new
|
elements = Array(HeaderType).new
|
||||||
order_keys = Array(OrderKey).new
|
order_keys = Array(OrderKey).new
|
||||||
|
|
||||||
idx = 0
|
idx = 0
|
||||||
self.parse_header(header) do |h|
|
self.parse_header(header) do |h|
|
||||||
element = self.create_header h
|
element = HeaderType.new h
|
||||||
elements << element
|
elements << element
|
||||||
order_keys << OrderKey.new element.quality, idx, element.header
|
order_keys << OrderKey.new element.quality, idx, element.header
|
||||||
rescue ex
|
rescue ex
|
||||||
|
@ -85,7 +93,7 @@ abstract class Athena::Negotiation::AbstractNegotiator
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private def find_matches(headers : Array(ANG::BaseAccept), priorities : Indexable(ANG::BaseAccept)) : Array(ANG::AcceptMatch)
|
private def find_matches(headers : Array(HeaderType), priorities : Indexable(HeaderType)) : Array(ANG::AcceptMatch)
|
||||||
matches = [] of ANG::AcceptMatch
|
matches = [] of ANG::AcceptMatch
|
||||||
|
|
||||||
priorities.each_with_index do |priority, idx|
|
priorities.each_with_index do |priority, idx|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
require "./abstract_negotiator"
|
require "./abstract_negotiator"
|
||||||
|
|
||||||
# A `ANG::AbstractNegotiator` implementation to negotiate `ANG::AcceptCharset` headers.
|
# A `ANG::AbstractNegotiator` implementation to negotiate `ANG::AcceptCharset` headers.
|
||||||
class Athena::Negotiation::CharsetNegotiator < Athena::Negotiation::AbstractNegotiator
|
class Athena::Negotiation::CharsetNegotiator < Athena::Negotiation::AbstractNegotiator(Athena::Negotiation::AcceptCharset)
|
||||||
private def create_header(header : String) : ANG::BaseAccept
|
|
||||||
ANG::AcceptCharset.new header
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
require "./abstract_negotiator"
|
require "./abstract_negotiator"
|
||||||
|
|
||||||
# A `ANG::AbstractNegotiator` implementation to negotiate `ANG::AcceptEncoding` headers.
|
# A `ANG::AbstractNegotiator` implementation to negotiate `ANG::AcceptEncoding` headers.
|
||||||
class Athena::Negotiation::EncodingNegotiator < Athena::Negotiation::AbstractNegotiator
|
class Athena::Negotiation::EncodingNegotiator < Athena::Negotiation::AbstractNegotiator(Athena::Negotiation::AcceptEncoding)
|
||||||
private def create_header(header : String) : ANG::BaseAccept
|
|
||||||
ANG::AcceptEncoding.new header
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require "./abstract_negotiator"
|
require "./abstract_negotiator"
|
||||||
|
|
||||||
# A `ANG::AbstractNegotiator` implementation to negotiate `ANG::AcceptLanguage` headers.
|
# A `ANG::AbstractNegotiator` implementation to negotiate `ANG::AcceptLanguage` headers.
|
||||||
class Athena::Negotiation::LanguageNegotiator < Athena::Negotiation::AbstractNegotiator
|
class Athena::Negotiation::LanguageNegotiator < Athena::Negotiation::AbstractNegotiator(Athena::Negotiation::AcceptLanguage)
|
||||||
protected def match(accept : ANG::AcceptLanguage, priority : ANG::AcceptLanguage, index : Int32) : ANG::AcceptMatch?
|
protected def match(accept : ANG::AcceptLanguage, priority : ANG::AcceptLanguage, index : Int32) : ANG::AcceptMatch?
|
||||||
accept_base = accept.language
|
accept_base = accept.language
|
||||||
priority_base = priority.language
|
priority_base = priority.language
|
||||||
|
@ -20,8 +20,4 @@ class Athena::Negotiation::LanguageNegotiator < Athena::Negotiation::AbstractNeg
|
||||||
|
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
private def create_header(header : String) : ANG::BaseAccept
|
|
||||||
ANG::AcceptLanguage.new header
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require "./abstract_negotiator"
|
require "./abstract_negotiator"
|
||||||
|
|
||||||
# A `ANG::AbstractNegotiator` implementation to negotiate `ANG::Accept` headers.
|
# A `ANG::AbstractNegotiator` implementation to negotiate `ANG::Accept` headers.
|
||||||
class Athena::Negotiation::Negotiator < Athena::Negotiation::AbstractNegotiator
|
class Athena::Negotiation::Negotiator < Athena::Negotiation::AbstractNegotiator(Athena::Negotiation::Accept)
|
||||||
# TODO: Make this method less complex.
|
# TODO: Make this method less complex.
|
||||||
#
|
#
|
||||||
# ameba:disable Metrics/CyclomaticComplexity
|
# ameba:disable Metrics/CyclomaticComplexity
|
||||||
|
@ -63,8 +63,4 @@ class Athena::Negotiation::Negotiator < Athena::Negotiation::AbstractNegotiator
|
||||||
|
|
||||||
sub_type.split '+', limit: 2
|
sub_type.split '+', limit: 2
|
||||||
end
|
end
|
||||||
|
|
||||||
private def create_header(header : String) : ANG::BaseAccept
|
|
||||||
ANG::Accept.new header
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue