def self.validate(rule, str)
if rule == Integer then
begin
return Integer(str)
rescue ArgumentError
raise Error::NotInteger.new(str, rule)
end
end
if rule == Float then
begin
return Float(str)
rescue ArgumentError
raise Error::NotFloat.new(str, rule)
end
end
case rule
when Range then
if rule.first.is_a? Integer and rule.last.is_a? Integer then
validate(Integer, str)
raise Error::OutOfRange.new(str, rule) unless rule.include?(str.to_i)
return str.to_i
elsif rule.first.is_a? Numeric then
validate(Float, str)
raise Error::OutOfRange.new(str, rule) unless rule.include?(str.to_f)
return str.to_f
end
raise Error::OutOfRange.new(str, rule) unless rule.include?(str)
return str
when Regexp then
raise Error::RegexpMismatch.new(str, rule) unless rule =~ str
return str
when Proc then
ret = rule.call(str)
return ret if ret
raise Error::InvalidValue.new(str, rule)
when Array then
rule.each do |i|
begin
return self.validate(i, str)
rescue Error
nil
end
end
raise Error::InvalidValue.new(str, rule)
when Hash then
ret = {}
rule.each do |k,v|
case k
when :any
ret[k] = self.validate(v, str)
when :all
ret[k] = v.map do |i|
self.validate(i, str)
end
when :rule
ret[k] = self.validate(v, str)
when :length
begin
self.validate v, str.length.to_s
ret[k] = str
rescue Error
raise Error::InvalidLength.new(str, rule)
end
when :maxlength
raise Error::TooLong.new(str, rule) unless str.length <= v
ret[k] = str
when :minlength
raise Error::TooShort.new(str, rule) unless str.length >= v
ret[k] = str
when :charlength
begin
self.validate v, str.split(//).length.to_s
ret[k] = str
rescue Error
raise Error::InvalidLength.new(str, rule)
end
when :maxcharlength
raise Error::TooLong.new(str, rule) unless str.split(//).length <= v
ret[k] = str
when :mincharlength
raise Error::TooShort.new(str, rule) unless str.split(//).length >= v
ret[k] = str
else
raise ArgumentError, "Invalid key: #{k}"
end
end
return ret
when Class then
begin
return rule.new(str)
rescue
raise Error::InvalidValue.new(str, rule)
end
else
return rule if rule.to_s == str
end
raise Error::InvalidValue.new(str, rule)
end