forked from theforeman/foreman
-
Notifications
You must be signed in to change notification settings - Fork 0
/
caster.rb
123 lines (108 loc) · 2.74 KB
/
caster.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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].nil? ? @item.send(@options[:attribute_name]) : @options[:value]
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
return nil if value == ""
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_integer
end
end
end
def cast_array
return value if value.is_a? Array
return value.to_a if !value.is_a?(String) && 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.safe_load(value, permitted_classes: [Symbol])
end
def load_yaml_or_json
return value unless value.is_a? String
begin
YAML.safe_load(value, permitted_classes: [Symbol])
rescue Psych::SyntaxError
JSON.load value
end
end
end
end
end