class RoadForest::ContentHandling::MediaType

@credit goes to Sean Cribbs & Ruby Webmachine for the basis of this code

Encapsulates a MIME media type, with logic for matching types.

Constants

MEDIA_TYPE_REGEX

Matches valid media types

PARAMS_REGEX

Matches sub-type parameters

Attributes

params[RW]

@return [Hash] any type parameters, e.g. charset

quality[R]
type[RW]

@return [String] the MIME media type

Public Class Methods

new(type, params={}) click to toggle source

@param [String] type the main media type, e.g. application/json @param [Hash] params the media type parameters

# File lib/roadforest/content-handling/media-type.rb, line 48
def initialize(type, params={})
  @type, @params = type, params
  @quality = (@params.delete('q') || "1.0").to_f
end
parse(*args) click to toggle source

Creates a new MediaType by parsing an alternate representation. @param [MediaType, String, Array<String,Hash>] obj the raw type

to be parsed

@return [MediaType] the parsed media type @raise [ArgumentError] when the type could not be parsed

# File lib/roadforest/content-handling/media-type.rb, line 18
def self.parse(*args)
  if args.length == 1
    obj = args.first
  else
    obj = args
  end

  if obj.is_a? MediaType
    obj
  elsif obj.is_a? String and !(match = MEDIA_TYPE_REGEX.match(obj)).nil?
    type, raw_params = *match[1,2]
    params = Hash[raw_params.scan(PARAMS_REGEX)]
    new(type, params)
  elsif Array === obj && String === obj[0] && Hash === obj[1]
    type = parse(obj[0])
    type.params.merge!(obj[1])
    type
  else
    raise ArgumentError, "Invalid media type #{obj.inspect}"
  end
end

Public Instance Methods

==(other) click to toggle source

@return [true,false] Are these two types strictly equal? @param other the other media type. @see MediaType.parse

# File lib/roadforest/content-handling/media-type.rb, line 64
def ==(other)
  other = self.class.parse(other)
  other.type == type && other.params == params
end
=~(other)
Alias for: match?
accept_header() click to toggle source
# File lib/roadforest/content-handling/media-type.rb, line 106
def accept_header
  "#{type};q=#{quality}#{params_for_header}"
end
content_type_header() click to toggle source
# File lib/roadforest/content-handling/media-type.rb, line 110
def content_type_header
  "#{type}#{params_for_header}"
end
Also aliased as: to_s
exact_match?(other) click to toggle source

Detects whether this {MediaType} matches the other {MediaType}, taking into account wildcards. Sub-type parameters are treated strictly. @param [MediaType, String, Array<String,Hash>] other the other type @return [true,false] whether it is an acceptable match

# File lib/roadforest/content-handling/media-type.rb, line 74
def exact_match?(other)
  other = self.class.parse(other)
  type_matches?(other) && other.params == params
end
major() click to toggle source

@return [String] The major type, e.g. “application”, “text”, “image”

# File lib/roadforest/content-handling/media-type.rb, line 116
def major
  @major ||= type.split("/").first
end
match?(other) click to toggle source

Detects whether the {MediaType} is an acceptable match for the other {MediaType}, taking into account wildcards and satisfying all requested parameters, but allowing this type to have extra specificity. @param [MediaType, String, Array<String,Hash>] other the other type @return [true,false] whether it is an acceptable match

# File lib/roadforest/content-handling/media-type.rb, line 85
def match?(other)
  other = self.class.parse(other)
  type_matches?(other) && params_match?(other.params)
end
Also aliased as: =~
matches_all?() click to toggle source

Detects whether the {MediaType} represents an open wildcard type, that is, “/” without any {#params}.

# File lib/roadforest/content-handling/media-type.rb, line 57
def matches_all?
  @type == "*/*" && @params.empty?
end
minor() click to toggle source

@return [String] the minor or sub-type, e.g. “json”, “html”, “jpeg”

# File lib/roadforest/content-handling/media-type.rb, line 121
def minor
  @minor ||= type.split("/").last
end
params_for_header() click to toggle source
# File lib/roadforest/content-handling/media-type.rb, line 102
def params_for_header
  params.map {|k,v| ";#{k}#{v ? "=":""}#{v}" }.join("")
end
params_match?(other) click to toggle source

Detects whether the passed sub-type parameters are all satisfied by this {MediaType}. The receiver is allowed to have other params than the ones specified, but all specified must be equal. @param [Hash] params the requested params @return [true,false] whether it is an acceptable match

# File lib/roadforest/content-handling/media-type.rb, line 96
def params_match?(other)
  other.all? do |k,v|
    params[k] == v
  end
end
precedence_index() click to toggle source
# File lib/roadforest/content-handling/media-type.rb, line 125
def precedence_index
  [
    @major == "*" ? 0 : 1,
    @minor == "*" ? 0 : 1,
    (@params.keys - %w{q}).length
  ]
end
to_s()
Alias for: content_type_header
type_matches?(other) click to toggle source

@param [MediaType] other the other type @return [true,false] whether the main media type is acceptable,

ignoring params and taking into account wildcards
# File lib/roadforest/content-handling/media-type.rb, line 136
def type_matches?(other)
  other = self.class.parse(other)
  if ["*", "*/*", type].include?(other.type)
    true
  else
    other.major == major && other.minor == "*"
  end
end