Skip to content

Instantly share code, notes, and snippets.

@hirayama
Created March 1, 2020 06:05
Show Gist options
  • Save hirayama/c3465e9fdc250ae04a021064930df36b to your computer and use it in GitHub Desktop.
Save hirayama/c3465e9fdc250ae04a021064930df36b to your computer and use it in GitHub Desktop.
simple ruby json schema validator
require "set"
module JsonSchemValidator
TYPES = {
"Hash" => Hash,
"hash" => Hash,
"object" => Hash,
"Array" => Array,
"array" => Array,
"list" => Array,
"Integer" => Integer,
"integer" => Integer,
"int" => Integer,
"Float" => Float,
"float" => Float,
"String" => String,
"string" => String,
"Boolean" => [TrueClass, FalseClass],
"boolean" => [TrueClass, FalseClass],
"Bool" => [TrueClass, FalseClass],
"bool" => [TrueClass, FalseClass],
}
def self.validate(json, yaml)
def self.check(key, value, schema)
raise Exception.new("Schema is InValid: need Type") unless schema.key? 'type'
raise Exception.new("Schema is InValid: #{schema['type']} is unknown") unless TYPES.key? schema['type']
type = TYPES[schema['type']]
if type == Hash
raise Exception.new("Json is InValid: #{key} must be Hash") unless valid_type? value, type
raise Exception.new("Json is InValid: #{key} must be required sufficient properties, nearby #{schema['required'].join(',')}") unless schema['required'].to_set.subset?(value.keys.to_set)
value.each do |child_key, child_value|
check_each(child_key, child_value, schema['properties'][child_key])
end
elsif type == Array
raise Exception.new("Json is InValid: #{key} must be Array") unless valid_type? value, type
raise Exception.new("Schema is InValid: #{key} need items") unless schema.key? 'items'
value.each do |item|
check_each("ArrayItems::#{key}", item, schema['items'])
end
else
raise Exception.new("Json is InValid: #{key} must be #{schema['type']}") unless valid_type? value, type
end
end
def self.valid_type?(value, type)
if type.is_a? Array
type.inject(false){|bool, _type| (bool or value.is_a? _type)}
else
value.is_a? type
end
end
check("schema", json, yaml)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment