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
@return [Hash] any type parameters, e.g. charset
@return [String] the MIME media type
Public Class Methods
@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
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
@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
# File lib/roadforest/content-handling/media-type.rb, line 106 def accept_header "#{type};q=#{quality}#{params_for_header}" end
# File lib/roadforest/content-handling/media-type.rb, line 110 def content_type_header "#{type}#{params_for_header}" end
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
@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
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
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
@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
# File lib/roadforest/content-handling/media-type.rb, line 102 def params_for_header params.map {|k,v| ";#{k}#{v ? "=":""}#{v}" }.join("") end
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
# 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
@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