Project

General

Profile

Download (2.61 KB) Statistics
| Branch: | Tag: | Revision:
module Foreman
module Parameters
class Caster
attr_reader :value

def initialize(item, options = {})
defaults = {
:attribute_name => :value,
:to => :string
}
options.reverse_merge!(defaults)
@item, @options = item, options
@value = @options[:value] || @item.send(@options[:attribute_name])
end

def cast!
@item.send("#{@options[:attribute_name]}=", casted_value)
end

def cast
casted_value
end

private

def casted_value
case @options[:to].to_s
when "string"
cast_string
when "integer"
cast_integer
when "real"
cast_real
when "boolean"
cast_boolean
when "array"
cast_array
when "hash"
cast_hash
when "json"
cast_json
when "yaml"
cast_yaml
when nil, ""
value
else
Rails.logger.warn("Unable to type cast #{value} to #{@options[:to]}")
raise TypeError
end
end

def cast_string
value.to_s
end

def cast_boolean
val = Foreman::Cast.to_bool(value)
return val if [true, false].include?(val)
raise TypeError
end

def cast_integer
return value.to_i if value.is_a?(Numeric)

if value.is_a?(String)
if value =~ /^0x[0-9a-f]+$/i
value.to_i(16)
elsif value =~ /^0[0-7]+$/
value.to_i(8)
elsif value =~ /^-?\d+$/
value.to_i
else
raise TypeError
end
end
end

def cast_real
return value if value.is_a? Numeric
if value.is_a?(String)
if value =~ /\A[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?\Z/
value.to_f
else
cast_value_integer value
end
end
end

def cast_array
return value if value.is_a? Array
return value.to_a if not value.is_a? String and value.is_a? Enumerable
val = load_yaml_or_json
raise TypeError unless val.is_a? Array
val
end

def cast_hash
return value if value.is_a? Hash
val = load_yaml_or_json
raise TypeError unless val.is_a? Hash
val
end

def cast_json
JSON.load value
end

def cast_yaml
YAML.load value
end

def load_yaml_or_json
return value unless value.is_a? String
begin
JSON.load value
rescue
YAML.load value
end
end
end
end
end
(1-1/2)