class NiceHash
def NiceHash.validate(patterns_hash, values_hash_to_validate, only_patterns: true)
if patterns_hash.kind_of?(Array)
pattern_hash = patterns_hash[0]
select_hash_key = patterns_hash[1]
elsif patterns_hash.kind_of?(Hash)
pattern_hash = patterns_hash
select_hash_key = nil
else
puts "NiceHash.validate wrong pattern_hash supplied #{patterns_hash.inspect}"
return { error: :error }
end
values = values_hash_to_validate
if pattern_hash.keys.size == get_all_keys(pattern_hash).size and values.keys.size != get_all_keys(values) and
pattern_hash.keys.size == pattern_hash.keys.flatten.size pattern_hash = values.set_values(pattern_hash)
end
results = {}
same_values = {}
if pattern_hash.kind_of?(Hash) and pattern_hash.size > 0
pattern_hash.each { |key, value|
if key.kind_of?(Array)
same_values[key[0]] = key.dup
same_values[key[0]].shift
key = key[0]
end
if value.kind_of?(Hash)
if !select_hash_key.nil? and value.keys.include?(select_hash_key)
value = value[select_hash_key]
elsif values.keys.include?(key) and values[key].kind_of?(Hash)
res = NiceHash.validate([value, select_hash_key], values[key], only_patterns: only_patterns)
results[key] = res if res.size > 0
next
end
end
if values.keys.include?(key)
if value.kind_of?(String) or value.kind_of?(Symbol)
if ((StringPattern.optimistic and value.kind_of?(String)) or value.kind_of?(Symbol)) and value.to_s.scan(/^!?\d+-?\d*:.+/).size > 0
res = StringPattern.validate(pattern: value, text: values[key])
results[key] = res if res.size > 0
elsif !only_patterns and ((StringPattern.optimistic and value.kind_of?(String)) or value.kind_of?(Symbol)) and value.to_s.scan(/^([\w\s\-]+\|)+[\w\s\-]+$/).size > 0
results[key] = false unless value.to_s.split("|").include?(values[key])
elsif !only_patterns
results[key] = false unless value.to_s == values[key].to_s
end
elsif value.kind_of?(Range)
if value.size.to_s == 'Infinity'
if values[key].class != value.first.class
results[key] = false
elsif values[key] < value.first
results[key] = false
end
else
if values[key].class != value.first.class or values[key].class != value.last.class
results[key] = false
elsif values[key] < value.first or values[key] > value.last
results[key] = false
end
end
elsif value.kind_of?(Class) and value == DateTime
if values[key].is_a?(String) and values[key].size == 24
d = Date.strptime(values[key], "%Y-%m-%dT%H:%M:%S.%LZ") rescue results[key] = false
elsif values[key].is_a?(Time) or values[key].is_a?(Date) or values[key].is_a?(DateTime)
else
results[key] = false
end
elsif value.kind_of?(Module) and value == Boolean
results[key] = false unless values[key].is_a?(Boolean)
elsif value.kind_of?(Regexp)
rex = Regexp.new("^#{value}$")
unless values[key].to_s.match?(rex)
results[key] = false
end
elsif value.kind_of?(Array)
array_pattern = false
complex_data = false
value.each { |v|
if (v.kind_of?(String) or v.kind_of?(Symbol)) and StringPattern.analyze(v, silent: true).kind_of?(StringPattern::Pattern)
if value.is_a?(Array) and value.size == 1 and values[key].is_a?(Array)
results[key] ||= []
values[key].each do |vk|
res = StringPattern.validate(pattern: value[0], text: vk)
results[key] << res
end
if results[key].flatten.size == 0
results.delete(key)
end
else
res = StringPattern.validate(pattern: value, text: values[key])
results[key] = res if res == false
end
array_pattern = true
break
elsif v.kind_of?(Hash) or v.kind_of?(Array) or v.kind_of?(Struct)
complex_data = true
break
end
}
unless array_pattern or results.include?(key)
if value.size == 1 and values[key].is_a?(Array) and values[key].size > 0
i = 0
if values[key].class == value.class
values[key].each do |v|
if value[0].is_a?(Hash)
res = NiceHash.validate([value[0], select_hash_key], v, only_patterns: only_patterns)
else
res = NiceHash.validate([{ key => value[0] }, select_hash_key], { key => v }, only_patterns: only_patterns)
array_pattern = true
end
if res.size > 0
results[key] = Array.new() if !results.keys.include?(key)
results[key][i] = res
end
i += 1
end
else
results[key] = false
end
else
i = 0
value.each { |v|
if v.is_a?(Hash)
res = NiceHash.validate([v, select_hash_key], values[key][i], only_patterns: only_patterns)
elsif v.is_a?(Array)
res = NiceHash.validate([{ key => v }, select_hash_key], { key => values[key][i] }, only_patterns: only_patterns)
array_pattern = true
else
res = []
end
if res.size > 0
results[key] = Array.new() if !results.keys.include?(key)
results[key][i] = res
end
i += 1
}
end
end
unless array_pattern or only_patterns or results.include?(key) or complex_data
results[key] = false unless value == values[key]
end
else
unless only_patterns or value.kind_of?(Proc)
results[key] = false unless value == values[key]
end
end
if same_values.include?(key)
same_values[key].each { |k|
if values.keys.include?(k)
if values[key] != values[k]
results[k] = "Not equal to #{key}"
end
end
}
end
end
}
end
return results
end
end