class Hv::Schema

Public Class Methods

new(schema={}, &block) click to toggle source
# File lib/hv/schema.rb, line 4
def initialize(schema={}, &block)
  @schema = schema
  @custom_validators = {}
  @custom_validators_keys = []
  @errors_processor = Hv::ErrorsProcessor
  @i18n_errors = Hv::ErrorsProcessor.i18n_errors
  self.instance_eval(&block) if block_given?
end

Public Instance Methods

errors(errors_processor=nil, i18n_errors=nil) click to toggle source
# File lib/hv/schema.rb, line 29
def errors(errors_processor=nil, i18n_errors=nil)
  i18n_errors = i18n_errors || @i18n_errors
  errors_processor = errors_processor || @errors_processor
  errors_processor.call(@result, i18n_errors)
end
result() click to toggle source
# File lib/hv/schema.rb, line 13
def result
  @result
end
set_error_processor(error_processor) click to toggle source
# File lib/hv/schema.rb, line 44
def set_error_processor(error_processor)
  @errors_processor = error_processor
end
set_i18n_errors(hash) click to toggle source
# File lib/hv/schema.rb, line 48
def set_i18n_errors(hash)
  @i18n_errors = hash
end
set_schema(schema) click to toggle source
# File lib/hv/schema.rb, line 17
def set_schema(schema)
  @schema = schema
end
validate(custom_validator_name, &block) click to toggle source
# File lib/hv/schema.rb, line 35
def validate(custom_validator_name, &block)
  @custom_validators[custom_validator_name] = block
end
validates?(input) click to toggle source
# File lib/hv/schema.rb, line 21
def validates?(input)
  @skip_paths = []
  @result = []
  validate_schema(@schema, input, [])
  run_custom_validators(input)
  @result.empty?
end
validator(key, &block) click to toggle source
# File lib/hv/schema.rb, line 39
def validator(key, &block)
  @custom_validators_keys << key
  define_singleton_method "validate_#{key}", block
end

Private Instance Methods

add_error(path, key, _spec, value) click to toggle source
# File lib/hv/schema.rb, line 75
def add_error(path, key, _spec, value)
  @result << [path, key, _spec, value]
end
allowed_validators() click to toggle source
# File lib/hv/schema.rb, line 59
def allowed_validators
  [:optional?, :format?, :min_size?, :max_size?, :size?, :lt?, :gt?, :types?, :type?, :enum?, :proc?, :array?, :empty?]
end
optional_attr?(path=[]) click to toggle source
# File lib/hv/schema.rb, line 98
def optional_attr?(path=[])
  if path.empty?
    @schema[:optional?]
  else
    (@schema.dig(*path) || {})[:optional?]
  end
end
parent_is_optional?(path) click to toggle source
# File lib/hv/schema.rb, line 63
def parent_is_optional?(path)
  @skip_paths.any? { |parent_path|
    (parent_path - path).empty?
  }
end
run_custom_validators(input) click to toggle source
# File lib/hv/schema.rb, line 69
def run_custom_validators(input)
  @custom_validators.each do |name, blk|
    blk.call(input)
  end
end
validate_array?(spec, values, path=nil) click to toggle source
# File lib/hv/schema.rb, line 157
def validate_array?(spec, values, path=nil)
  return false unless values.is_a?(Array)
  values.to_enum.with_index.all? {|value, index|
    validate_schema(spec, value, [path, index].flatten)
  }
end
validate_enum?(spec, value, path) click to toggle source
# File lib/hv/schema.rb, line 106
def validate_enum?(spec, value, path)
  spec.include?(value)
end
validate_format?(spec, value, path) click to toggle source
# File lib/hv/schema.rb, line 149
def validate_format?(spec, value, path)
  if value.respond_to? :match?
    value.match?(spec)
  else
    false
  end
end
validate_gt?(spec, value, path) click to toggle source
# File lib/hv/schema.rb, line 145
def validate_gt?(spec, value, path)
  validate_size(spec, value, '>')
end
validate_lt?(spec, value, path) click to toggle source
# File lib/hv/schema.rb, line 141
def validate_lt?(spec, value, path)
  validate_size(spec, value, '<')
end
validate_max_size?(spec, value, path) click to toggle source
# File lib/hv/schema.rb, line 133
def validate_max_size?(spec, value, path)
  validate_size(spec, value, '<=')
end
validate_min_size?(spec, value, path) click to toggle source
# File lib/hv/schema.rb, line 129
def validate_min_size?(spec, value, path)
  validate_size(spec, value, '>=')
end
validate_schema(spec, value, path=nil) click to toggle source
# File lib/hv/schema.rb, line 79
def validate_schema(spec, value, path=nil)
  spec.each do |key, _spec|
    if !validator_key?(key)
      _value = value[key] rescue nil
      validate_schema(_spec, _value, [path, key].flatten)
    else
      match = if value.nil? && optional_attr?(path)
        @skip_paths << path
        true
      else
        next if key == :optional?
        next if parent_is_optional?(path)
        send("validate_#{key}",_spec, value, path)
      end
      add_error(path, key, _spec, value) unless match
    end
  end
end
validate_size(spec, value, oper) click to toggle source
# File lib/hv/schema.rb, line 120
def validate_size(spec, value, oper)
  case value
  when Enumerable, String
    value.size.send(oper, spec)
  when Numeric
    value.send(oper, spec)
  end
end
validate_size?(spec, value, path) click to toggle source
# File lib/hv/schema.rb, line 137
def validate_size?(spec, value, path)
  validate_size(spec, value, '==')
end
validate_type?(spec, value, path) click to toggle source
# File lib/hv/schema.rb, line 116
def validate_type?(spec, value, path)
  value.is_a?(spec)
end
validate_types?(spec, value, path) click to toggle source
# File lib/hv/schema.rb, line 110
def validate_types?(spec, value, path)
  raise "Argument for :types? must be an array of types" unless spec.is_a? Array
  spec.any? { |_type| value.is_a?(_type) }
end
validator_key?(key) click to toggle source
# File lib/hv/schema.rb, line 54
def validator_key?(key)
  allowed_validators.include?(key) ||
  @custom_validators_keys.include?(key)
end