Sha256: cf29cc7e5f71ad6885789d98500dca7dd2f15b7f4f6f80ec416d1ebd8f3f2c96

Contents?: true

Size: 1.25 KB

Versions: 2

Compression:

Stored size: 1.25 KB

Contents

module AcceptHeaders
  module Negotiatable
    class Error < StandardError; end
    class ParseError < Error; end

    Q_PATTERN = /(?:\A|;)\s*(?<exists>qs*\=)\s*(?:(?<q>0\.\d{1,3}|[01])|(?:[^;]*))\s*(?:\z|;)/

    attr_reader :list

    def initialize(header)
      @list = parse(header)
    end

    def negotiate(supported)
      return nil if list.empty?
      supported = [*supported]
      # TODO: Maybe q=0 should be first by default when sorting
      rejects, acceptable = list.partition { |m| m.q == 0.0 }
      (rejects + acceptable).each do |part|
        supported.each do |support|
          if part.match(support)
            if part.q == 0.0
              next
            else
              return { supported: support, matched: part }
            end
          end
        end
      end
      nil
    end

    def accept?(other)
      negotiate(other) ? true : false
    end

    private
    def parse(header)
      raise NotImplementedError.new("#parse(header) is not implemented")
    end

    def parse_q(header)
      q = 1
      return q unless header
      q_match = Q_PATTERN.match(header)
      if q_match && q_match[:exists]
        if q_match[:q]
          q = q_match[:q]
        else
          q = 0.001
        end
      end
      q
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
accept_headers-0.0.7 lib/accept_headers/negotiatable.rb
accept_headers-0.0.6 lib/accept_headers/negotiatable.rb