module Sinatra::Param

Constants

Boolean
VERSION

Public Instance Methods

param(name, type, options = {}) click to toggle source
# File lib/sinatra/param.rb, line 14
def param(name, type, options = {})
  name = name.to_s

  return unless params.member?(name) or options.has_key?(:default) or options[:required]

  begin
    params[name] = coerce(name, params[name], type, options)
    params[name] = (options[:default].call if options[:default].respond_to?(:call)) || options[:default] if params[name].nil? and options.has_key?(:default)
    params[name] = options[:transform].to_proc.call(params[name]) if params[name] and options[:transform]
    validate!(params[name], name, options)
    params[name]
  rescue InvalidParameterError => exception
    if options[:raise] or (settings.raise_sinatra_param_exceptions rescue false)
      exception.param, exception.options = name, options
      raise exception
    end

    error = options[:message] || exception.to_s

    if content_type and content_type.match(mime_type(:json))
      error = {error: error}.to_json
    else
      content_type 'text/plain'
    end

    halt 400, error
  end
end

Private Instance Methods

coerce(param_name, param, type, options = {}) click to toggle source
  halt 400, error
end

end

# File lib/sinatra/param.rb, line 112
def coerce(param_name, param, type, options = {})
  begin
    return nil if param.nil?
    return param if (param.is_a?(type) rescue false)
    return Integer(param, 10) if type == Integer
    return Float(param) if type == Float
    return String(param) if type == String
    return Date.parse(param) if type == Date
    return Time.parse(param) if type == Time
    return DateTime.parse(param) if type == DateTime
    return Array(param.split(options[:delimiter] || ",")) if type == Array
    return Hash[param.split(options[:delimiter] || ",").map{|c| c.split(options[:separator] || ":")}] if type == Hash
    if [TrueClass, FalseClass, Boolean].include? type
      coerced = /^(false|f|no|n|0)$/i === param.to_s ? false : /^(true|t|yes|y|1)$/i === param.to_s ? true : nil
      raise ArgumentError if coerced.nil?
      return coerced
    end
    return nil
  rescue ArgumentError
    raise InvalidParameterError, "Parameter #{param_name} '#{param}' is not a valid #{type}"
  end
end
validate!(param, param_name, options) click to toggle source
# File lib/sinatra/param.rb, line 135
def validate!(param, param_name, options)
  options.each do |key, value|
    case key
    when :required
      raise InvalidParameterError, "Parameter #{param_name} is required" if value && param.nil?
    when :blank
      raise InvalidParameterError, "Parameter #{param_name} cannot be blank" if !value && case param
      when String
        !(/\S/ === param)
      when Array, Hash
        param.empty?
      else
        param.nil?
      end
    when :format
      raise InvalidParameterError, "Parameter #{param_name} must be a string if using the format validation" unless param.kind_of?(String)
      raise InvalidParameterError, "Parameter #{param_name} must match format #{value}" unless param =~ value
    when :is
      raise InvalidParameterError, "Parameter #{param_name} must be #{value}" unless param === value
    when :in, :within, :range
      raise InvalidParameterError, "Parameter #{param_name} must be within #{value}" unless param.nil? || case value
      when Range
        value.include?(param)
      else
        Array.wrap(value).any? {|v| Array.wrap(param).include?(v)}
      end
    when :min
      raise InvalidParameterError, "Parameter #{param_name} cannot be less than #{value}" unless param.nil? || value <= param
    when :max
      raise InvalidParameterError, "Parameter #{param_name} cannot be greater than #{value}" unless param.nil? || value >= param
    when :min_length
      raise InvalidParameterError, "Parameter #{param_name} cannot have length less than #{value}" unless param.nil? || value <= param.length
    when :max_length
      raise InvalidParameterError, "Parameter #{param_name} cannot have length greater than #{value}" unless param.nil? || value >= param.length
    when :custom
        raise InvalidParameterError, "Parameter #{param_name} is not valid" unless value.to_proc.call(param)
    end
  end
end