lib/sinatra/swagger-exposer/processing/swagger-primitive-value-processor.rb
require 'date'
require_relative 'swagger-base-value-processor'
require_relative '../swagger-parameter-helper'
require_relative '../swagger-invalid-exception'
module Sinatra
module SwaggerExposer
module Processing
# Validate primitive value
class SwaggerPrimitiveValueProcessor < SwaggerBaseValueProcessor
include Sinatra::SwaggerExposer::SwaggerParameterHelper
attr_reader :type, :params
# Initialize
# @param name [String] the name
# @param required [TrueClass] if the parameter is required
# @param type [String] the type name
# @param default [Object] the default value
# @param params [Hash] parameters
def initialize(name, required, type, default, params)
super(name, required, default)
@type = type
@params = params
end
def useful?
super ||
[TYPE_NUMBER, TYPE_INTEGER, TYPE_BOOLEAN, TYPE_DATE_TIME].include?(@type) || # Must check type
(@params.key? PARAMS_MIN_LENGTH) || (@params.key? PARAMS_MAX_LENGTH) # Must check string
end
# Dispatch method
def validate_value(value)
case @type
when TYPE_NUMBER
return validate_value_number(value)
when TYPE_INTEGER
return validate_value_integer(value)
when TYPE_BOOLEAN
return validate_value_boolean(value)
when TYPE_DATE_TIME
return validate_value_date_time(value)
else
return validate_value_string(value)
end
end
# Validate a boolean
def validate_value_boolean(value)
if (value == 'true') || value.is_a?(TrueClass)
true
elsif (value == 'false') || value.is_a?(FalseClass)
false
else
raise SwaggerInvalidException.new("Value [#{name}] should be an boolean but is [#{value}]")
end
end
# Validate an integer
def validate_value_integer(value)
begin
f = Float(value)
i = Integer(value)
if f == i
i
else
raise SwaggerInvalidException.new("Value [#{name}] should be an integer but is [#{value}]")
end
value = Integer(value)
validate_numerical_value(value)
value
rescue ArgumentError
raise SwaggerInvalidException.new("Value [#{name}] should be an integer but is [#{value}]")
rescue TypeError
raise SwaggerInvalidException.new("Value [#{name}] should be an integer but is [#{value}]")
end
end
# Validate a number value
def validate_value_number(value)
begin
value = Float(value)
validate_numerical_value(value)
return value
rescue ArgumentError
raise SwaggerInvalidException.new("Value [#{name}] should be a float but is [#{value}]")
rescue TypeError
raise SwaggerInvalidException.new("Value [#{name}] should be a float but is [#{value}]")
end
end
# Validate a numerical value
# @param value [Numeric] the value
def validate_numerical_value(value)
validate_numerical_value_internal(
value,
PARAMS_MINIMUM,
PARAMS_EXCLUSIVE_MINIMUM,
'>=',
'>')
validate_numerical_value_internal(
value,
PARAMS_MAXIMUM,
PARAMS_EXCLUSIVE_MAXIMUM,
'<=',
'<')
end
# Validate a date time
def validate_value_date_time(value)
begin
DateTime.rfc3339(value)
rescue ArgumentError
raise SwaggerInvalidException.new("Value [#{name}] should be a date time but is [#{value}]")
end
end
# Validate a string
def validate_value_string(value)
if value
validate_value_string_length(value, PARAMS_MIN_LENGTH, '>=')
validate_value_string_length(value, PARAMS_MAX_LENGTH, '<=')
end
value
end
# Validate the length of a string
# @param value the value to check
# @param limit_param_name [Symbol] the param that contain the value to compare to
# @param limit_param_method [String] the comparison method to call
def validate_value_string_length(value, limit_param_name, limit_param_method)
if @params.key? limit_param_name
target_value = @params[limit_param_name]
unless value.length.send(limit_param_method, target_value)
raise SwaggerInvalidException.new("Value [#{name}] length should be #{limit_param_method} than #{target_value} but is #{value.length} for [#{value}]")
end
end
end
# Validate the value of a number
# @param value the value to check
# @param limit_param_name [Symbol] the param that contain the value to compare to
# @param exclusive_limit_param_name [Symbol] the param that indicates if the comparison is absolute
# @param limit_param_method [String] the comparison method to call
# @param exclusive_limit_param_method [String] the absolute comparison method to call
def validate_numerical_value_internal(value, limit_param_name, exclusive_limit_param_name, limit_param_method, exclusive_limit_param_method)
if @params.key? limit_param_name
target_value = @params[limit_param_name]
method_to_call = @params[exclusive_limit_param_name] ? exclusive_limit_param_method : limit_param_method
unless value.send(method_to_call, target_value)
raise SwaggerInvalidException.new("Value [#{name}] should be #{method_to_call} than [#{target_value}] but is [#{value}]")
end
end
end
end
end
end
end