Module: ClassyHash::Generate

Defined in:
lib/classy_hash/generate.rb

Overview

This module contains helpers that generate constraints for common ClassyHash validation tasks.

Defined Under Namespace

Classes: Composite

Class Method Summary collapse

Class Method Details

.all(*constraints) ⇒ Object

Generates a constraint that requires a value to match all of the given constraints. If no constraints are given, always passes.

Raises an error if no constraints are given.

Example:

schema = {
  a: CH::G.all(Integer, 1..100, CH::G.not(Set.new([7, 13])))
}
ClassyHash.validate({ a: 25 }, schema)


45
46
47
# File 'lib/classy_hash/generate.rb', line 45

def self.all(*constraints)
  Composite.new(constraints.freeze)
end

.array_length(length, *constraints) ⇒ Object

Generates a constraint that validates an Array’s length and contents using one or more constraints.

Example:

schema = {
  a: ClassyHash::Generate.array_length(4..5, Integer, String)
}
ClassyHash.validate({ a: [ 1, 2, 3, 'four', 5 ] }, schema)


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/classy_hash/generate.rb', line 115

def self.array_length(length, *constraints)
  raise 'one or more constraints must be provided' if constraints.empty?

  length_lambda = self.length(length)
  msg = "an Array of length #{length}"

  lambda {|v|
    if v.is_a?(Array)
      result = length_lambda.call(v)
      if result == true
        begin
          ClassyHash.validate({array: v}, {array: [constraints]})
          true
        rescue => e
          "valid: #{e}"
        end
      else
        msg
      end
    else
      msg
    end
  }
end

.enum(*args) ⇒ Object

Deprecated. Generates a ClassyHash constraint that ensures a value is equal to one of the arguments in args.

For new schemas, consider creating a Set with the enumeration elements.

Example:

schema = {
  a: ClassyHash::Generate.enum(1, 2, 3, 4)
}
ClassyHash.validate({ a: 1 }, schema)


73
74
75
# File 'lib/classy_hash/generate.rb', line 73

def self.enum(*args)
  Set.new(args)
end

.length(length) ⇒ Object

Generates a constraint that imposes a length limitation (an exact length or a range) on any type that responds to the :length method (e.g. String, Array, Hash).

Example:

schema = {
  a: ClassyHash::Generate.length(0..5)
}
ClassyHash.validate({a: '12345'}, schema)
ClassyHash.validate({a: [1, 2, 3, 4, 5]}, schema)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/classy_hash/generate.rb', line 87

def self.length(length)
  raise "length must be an Integer or a Range" unless length.is_a?(Integer) || length.is_a?(Range)

  if length.is_a?(Range) && !(length.min.is_a?(Integer) && length.max.is_a?(Integer))
    raise "Range length endpoints must be Integers"
  end

  lambda {|v|
    if v.respond_to?(:length)
      if v.length == length || (length.is_a?(Range) && length.cover?(v.length))
        true
      else
        "of length #{length}"
      end
    else
      "a type that responds to :length"
    end
  }
end

.not(*constraints) ⇒ Object

Generates a constraint that requires a value to match none of the given constraints.

Raises an error if no constraints are given.

Example:

schema = {
  a: CH::G.not(Rational, BigDecimal)
}
ClassyHash.validate({ a: 1.25 }, schema)


59
60
61
# File 'lib/classy_hash/generate.rb', line 59

def self.not(*constraints)
  Composite.new(constraints.freeze, true)
end

.string_length(length) ⇒ Object

Generates a constraint that validates the length of a String.

Example:

schema = {
  a: ClassyHash::Generate.string_length(3)
}
ClassyHash.validate({a: '123'}, schema)


147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/classy_hash/generate.rb', line 147

def self.string_length(length)
  length_lambda = self.length(length)
  msg = "a String of length #{length}"

  lambda {|v|
    if v.is_a?(String)
      length_lambda.call(v) == true || msg
    else
      msg
    end
  }
end