Class: HashValidator

Inherits:
Object
  • Object
show all
Defined in:
lib/hash_validator/hash_validator.rb

Defined Under Namespace

Classes: DSLProxy

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ HashValidator

Returns a new instance of HashValidator.



14
15
16
17
18
19
20
21
22
23
# File 'lib/hash_validator/hash_validator.rb', line 14

def initialize(opts = {})
  @template = {
    keys: {},
    opts: opts
  }

  @key_stack = []
  @dsl_proxy = DSLProxy.new(self)
  @default_value = :__no_value__
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ Object



102
103
104
105
106
107
108
# File 'lib/hash_validator/hash_validator.rb', line 102

def method_missing(m, *args, &block)
  if @dsl_proxy.respond_to?(m)
    @dsl_proxy.send(m, *args, &block)
  else
    super(m, *args, &block)
  end
end

Instance Attribute Details

#default_valueObject

Returns the value of attribute default_value.



3
4
5
# File 'lib/hash_validator/hash_validator.rb', line 3

def default_value
  @default_value
end

#dsl_proxyObject (readonly)

Returns the value of attribute dsl_proxy.



2
3
4
# File 'lib/hash_validator/hash_validator.rb', line 2

def dsl_proxy
  @dsl_proxy
end

Class Method Details

.new(*args) ⇒ Object



7
8
9
10
11
# File 'lib/hash_validator/hash_validator.rb', line 7

def new(*args)
  v = orig_new(*args)
  v.instance_exec(&Proc.new) if block_given?
  v
end

.orig_newObject



6
# File 'lib/hash_validator/hash_validator.rb', line 6

alias_method :orig_new, :new

Instance Method Details

#add_option(k, v) ⇒ Object



98
99
100
# File 'lib/hash_validator/hash_validator.rb', line 98

def add_option(k, v)
  top[:opts][k] = v
end

#cloneObject



33
34
35
36
37
# File 'lib/hash_validator/hash_validator.rb', line 33

def clone
  copy = HashValidator.new
  copy.instance_variable_set(:@template, Marshal.load(Marshal.dump(@template)))
  copy
end

#key(k, opts, &block) ⇒ Object



83
84
85
86
87
88
89
90
91
92
# File 'lib/hash_validator/hash_validator.rb', line 83

def key(k, opts, &block)
  top[:keys][k] = {
    opts: opts,
    keys: {}
  }

  @key_stack.push(k)
  @dsl_proxy.instance_exec(&block) if block_given?
  @key_stack.pop
end

#optsObject



25
26
27
# File 'lib/hash_validator/hash_validator.rb', line 25

def opts
  @template[:opts]
end

#overwrite_opts(opts) ⇒ Object



29
30
31
# File 'lib/hash_validator/hash_validator.rb', line 29

def overwrite_opts(opts)
  @template[:opts].merge(opts)
end

#topObject



94
95
96
# File 'lib/hash_validator/hash_validator.rb', line 94

def top
  @key_stack.inject(@template) { |ref, key| ref[:keys][key] } || @template
end

#valid?(hsh) ⇒ Boolean

Returns:

  • (Boolean)


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
# File 'lib/hash_validator/hash_validator.rb', line 39

def valid?(hsh)
  return false unless hsh.keys.all? { |key| top[:keys].include?(key) }

  top[:keys].each do |k, v|
    if !hsh.has_key?(k)
      if v[:opts][:required]
        return false
      else
        next
      end
    end
    
    input = hsh[k]

    # Check type of input
    return false unless input.is_a?(v[:opts][:type])

    if input.is_a?(Hash)
      @key_stack.push(k)

      valid?(input) or begin
        @key_stack = []
        return false
      end

      @key_stack.pop
    elsif input.is_a?(Array)
      return false if v[:opts][:allowed_values].present? &&
                      !input.all? {|_input| v[:opts][:allowed_values].include?(_input)}

      return false if v[:opts][:forbidden_values].present? &&
                      input.any? {|_input| v[:opts][:forbidden_values].include?(_input)}
    else
      return false if v[:opts][:allowed_values].present? &&
                      !v[:opts][:allowed_values].include?(hsh[k])

      return false if v[:opts][:forbidden_values].present? &&
                      v[:opts][:forbidden_values].include?(hsh[k])
    end
  end

  true
end