module Shaf::Responder

Constants

MEDIA_TYPE_SUFFIX_PATTERN

Public Class Methods

default() click to toggle source
# File lib/shaf/responder.rb, line 34
def default
  responders.default
end
default=(responder) click to toggle source
# File lib/shaf/responder.rb, line 30
def default=(responder)
  responders.default = responder
end
for(request, resource) click to toggle source
# File lib/shaf/responder.rb, line 20
def for(request, resource)
  return Responder::ProblemJson if resource.is_a?(Errors::NotAcceptableError)

  types = supported_responders_for(resource).map(&:mime_type)
  types = move_html_to_last(types)

  mime = preferred_type(request, types)
  responders[mime] or raise Errors::NotAcceptableError
end
register(responder) click to toggle source
# File lib/shaf/responder.rb, line 9
def register(responder)
  uninitialized << responder
end
unregister(responder) click to toggle source
# File lib/shaf/responder.rb, line 13
def unregister(responder)
  responders.delete_if { |_, r| r == responder }
  supported_responders.each do |_klass, responders|
    responders.delete_if { |r| r == responder }
  end
end

Private Class Methods

init_responders!() click to toggle source
# File lib/shaf/responder.rb, line 76
def init_responders!
  while responder = uninitialized.shift
    mime = responder.mime_type
    @responders[mime] = responder
  end
end
move_html_to_last(types) click to toggle source

We want to always be able to respond with text/html, but only when asked for (Accept header) to be able to let other more specific mime types take precedence we need to move text/html to the end of the array.

# File lib/shaf/responder.rb, line 93
def move_html_to_last(types)
  return types unless types.include? Html.mime_type

  (types - [Html.mime_type]) << Html.mime_type
end
preferred_type(request, types) click to toggle source
# File lib/shaf/responder.rb, line 55
def preferred_type(request, types)
  mime = request.preferred_type(types)
  return mime if mime

  request.accept.find do |accept|
    next if accept.match? MEDIA_TYPE_SUFFIX_PATTERN

    types.find do |type|
      m = type.match MEDIA_TYPE_SUFFIX_PATTERN
      next unless m

      format = "#{m[1]}/#{m[3]}"
      return type if accept.to_str == format
    end
  end
end
responders() click to toggle source
# File lib/shaf/responder.rb, line 83
def responders
  (@responders ||= {}).tap do
    init_responders!
  end
end
supported_responders() click to toggle source
# File lib/shaf/responder.rb, line 51
def supported_responders
  @supported_responders ||= Hash.new { |hash, key| hash[key] = Set.new }
end
supported_responders_for(resource) click to toggle source
# File lib/shaf/responder.rb, line 40
def supported_responders_for(resource)
  klass = resource.is_a?(Class) ? resource: resource.class
  if supported_responders[klass].empty?
    responders.each do |_mime, responder|
      next unless responder.can_handle? resource
      supported_responders[klass] << responder
    end
  end
  supported_responders[klass].to_a
end
uninitialized() click to toggle source
# File lib/shaf/responder.rb, line 72
def uninitialized
  @uninitialized ||= []
end