forked from mattt/sinatra-param
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparam.rb
105 lines (93 loc) · 3.26 KB
/
param.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
require 'sinatra/base'
require 'sinatra/param/version'
require 'time'
require 'date'
module Sinatra
module Param
class InvalidParameterError < StandardError; end
def param(name, type, options = {})
begin
params[name] = coerce(params[name], type, options) || options[:default]
params[name] = options[:transform].to_proc.call(params[name]) if options[:transform]
validate!(params[name], options)
rescue
error = "Invalid parameter, #{name}"
if content_type and content_type.match(mime_type(:json))
error = {message: error}.to_json
end
halt 406, error
end
end
def one_of(*names)
count = 0
names.each do |name|
if params[name] and present?(params[name])
count += 1
next unless count > 1
error = "Parameters #{names.join(', ')} are mutually exclusive"
if content_type and content_type.match(mime_type(:json))
error = {message: error}.to_json
end
halt 406, error
end
end
end
private
def coerce(param, type, options = {})
return nil if param.nil?
return param if (param.is_a?(type) rescue false)
return Integer(param) if type == Integer
return Float(param) if type == Float
return String(param) if type == String
return Time.parse(param) if type == Time
return Date.parse(param) if type == Date
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
return (/(false|f|no|n|0)$/i === param.to_s ? false : (/(true|t|yes|y|1)$/i === param.to_s ? true : nil)) if type == TrueClass || type == FalseClass || type == :boolean
return nil
end
def validate!(param, options)
options.each do |key, value|
case key
when :required
raise InvalidParameterError if value && param.nil?
when :blank
raise InvalidParameterError if !value && case param
when String
!(/\S/ === param)
when Array, Hash
param.empty?
else
param.nil?
end
when :is
raise InvalidParameterError unless value === param
when :in, :within, :range
raise InvalidParameterError unless param.nil? || case value
when Range
value.include?(param)
else
Array(value).include?(param)
end
when :min
raise InvalidParameterError unless param.nil? || value <= param
when :max
raise InvalidParameterError unless param.nil? || value >= param
when :min_length
raise InvalidParameterError unless param.nil? || value <= param.length
when :max_length
raise InvalidParameterError unless param.nil? || value >= param.length
end
end
end
# ActiveSupport #present? and #blank? without patching Object
def present?(object)
!blank?(object)
end
def blank?(object)
object.respond_to?(:empty?) ? object.empty? : !object
end
end
helpers Param
end