This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
module SafeYAML
|
||||
class Transform
|
||||
class ToBoolean
|
||||
include TransformationMap
|
||||
|
||||
set_predefined_values({
|
||||
"yes" => true,
|
||||
"on" => true,
|
||||
"true" => true,
|
||||
"no" => false,
|
||||
"off" => false,
|
||||
"false" => false
|
||||
})
|
||||
|
||||
def transform?(value)
|
||||
return false if value.length > 5
|
||||
return PREDEFINED_VALUES.include?(value), PREDEFINED_VALUES[value]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
module SafeYAML
|
||||
class Transform
|
||||
class ToDate
|
||||
def transform?(value)
|
||||
return true, Date.parse(value) if Parse::Date::DATE_MATCHER.match(value)
|
||||
return true, Parse::Date.value(value) if Parse::Date::TIME_MATCHER.match(value)
|
||||
false
|
||||
rescue ArgumentError
|
||||
return true, value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
module SafeYAML
|
||||
class Transform
|
||||
class ToFloat
|
||||
Infinity = 1.0 / 0.0
|
||||
NaN = 0.0 / 0.0
|
||||
|
||||
PREDEFINED_VALUES = {
|
||||
".inf" => Infinity,
|
||||
".Inf" => Infinity,
|
||||
".INF" => Infinity,
|
||||
"-.inf" => -Infinity,
|
||||
"-.Inf" => -Infinity,
|
||||
"-.INF" => -Infinity,
|
||||
".nan" => NaN,
|
||||
".NaN" => NaN,
|
||||
".NAN" => NaN,
|
||||
}.freeze
|
||||
|
||||
MATCHER = /\A[-+]?(?:\d[\d_]*)?\.[\d_]+(?:[eE][-+][\d]+)?\Z/.freeze
|
||||
|
||||
def transform?(value)
|
||||
return true, Float(value) if MATCHER.match(value)
|
||||
try_edge_cases?(value)
|
||||
end
|
||||
|
||||
def try_edge_cases?(value)
|
||||
return true, PREDEFINED_VALUES[value] if PREDEFINED_VALUES.include?(value)
|
||||
return true, Parse::Sexagesimal.value(value) if Parse::Sexagesimal::FLOAT_MATCHER.match(value)
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
module SafeYAML
|
||||
class Transform
|
||||
class ToInteger
|
||||
MATCHERS = Deep.freeze([
|
||||
/\A[-+]?(0|([1-9][0-9_,]*))\Z/, # decimal
|
||||
/\A0[0-7]+\Z/, # octal
|
||||
/\A0x[0-9a-f]+\Z/i, # hexadecimal
|
||||
/\A0b[01_]+\Z/ # binary
|
||||
])
|
||||
|
||||
def transform?(value)
|
||||
MATCHERS.each_with_index do |matcher, idx|
|
||||
value = value.gsub(/[_,]/, "") if idx == 0
|
||||
return true, Integer(value) if matcher.match(value)
|
||||
end
|
||||
try_edge_cases?(value)
|
||||
end
|
||||
|
||||
def try_edge_cases?(value)
|
||||
return true, Parse::Hexadecimal.value(value) if Parse::Hexadecimal::MATCHER.match(value)
|
||||
return true, Parse::Sexagesimal.value(value) if Parse::Sexagesimal::INTEGER_MATCHER.match(value)
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
module SafeYAML
|
||||
class Transform
|
||||
class ToNil
|
||||
include TransformationMap
|
||||
|
||||
set_predefined_values({
|
||||
"" => nil,
|
||||
"~" => nil,
|
||||
"null" => nil
|
||||
})
|
||||
|
||||
def transform?(value)
|
||||
return false if value.length > 4
|
||||
return PREDEFINED_VALUES.include?(value), PREDEFINED_VALUES[value]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
module SafeYAML
|
||||
class Transform
|
||||
class ToSymbol
|
||||
def transform?(value, options=SafeYAML::OPTIONS)
|
||||
if options[:deserialize_symbols] && value =~ /\A:./
|
||||
if value =~ /\A:(["'])(.*)\1\Z/
|
||||
return true, $2.sub(/^:/, "").to_sym
|
||||
else
|
||||
return true, value.sub(/^:/, "").to_sym
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
module SafeYAML
|
||||
class Transform
|
||||
module TransformationMap
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
|
||||
class CaseAgnosticMap < Hash
|
||||
def initialize(*args)
|
||||
super
|
||||
end
|
||||
|
||||
def include?(key)
|
||||
super(key.downcase)
|
||||
end
|
||||
|
||||
def [](key)
|
||||
super(key.downcase)
|
||||
end
|
||||
|
||||
# OK, I actually don't think it's all that important that this map be
|
||||
# frozen.
|
||||
def freeze
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def set_predefined_values(predefined_values)
|
||||
if SafeYAML::YAML_ENGINE == "syck"
|
||||
expanded_map = predefined_values.inject({}) do |hash, (key, value)|
|
||||
hash[key] = value
|
||||
hash[key.capitalize] = value
|
||||
hash[key.upcase] = value
|
||||
hash
|
||||
end
|
||||
else
|
||||
expanded_map = CaseAgnosticMap.new
|
||||
expanded_map.merge!(predefined_values)
|
||||
end
|
||||
|
||||
self.const_set(:PREDEFINED_VALUES, expanded_map.freeze)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user