Module: ComposableValidations

Includes:
Combinators, Comparison, Utils
Defined in:
lib/composable_validations.rb,
lib/composable_validations/version.rb,
lib/composable_validations/combinators.rb

Defined Under Namespace

Modules: Combinators, Comparison, Utils Classes: Errors

Constant Summary collapse

VERSION =
'0.0.10'

Instance Method Summary collapse

Methods included from Comparison

#comparison, #equal, #greater, #greater_or_equal, #in_range, #key_equal_to_key, #key_greater_or_equal_to_key, #key_greater_than_key, #key_less_or_equal_to_key, #key_less_than_key, #key_to_key_comparison, #less, #less_or_equal

Methods included from Utils

#default_errors, #error, #join, #validate

Methods included from Combinators

#fail_fast, #nil_or, #precheck, #run_all

Instance Method Details

#a_hash(*validators) ⇒ Object

it is named with prefix ‘a_’ to avoid conflict with built in hash method



17
18
19
# File 'lib/composable_validations.rb', line 17

def a_hash(*validators)
  fail_fast(just_hash, run_all(*validators))
end

#allowed_keys(*allowed_keys) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/composable_validations.rb', line 47

def allowed_keys(*allowed_keys)
  lambda do |h, errors, prefix|
    h.keys.inject(true) do |acc, key|
      if !allowed_keys.include?(key)
        error(errors, :allowed_keys, h, prefix, key)
      else
        acc && true
      end
    end
  end
end

#array(*validators) ⇒ Object



21
22
23
24
25
# File 'lib/composable_validations.rb', line 21

def array(*validators)
  fail_fast(
    just_array,
    run_all(*validators))
end

#at_least_one_of(*keys) ⇒ Object



190
191
192
193
194
195
# File 'lib/composable_validations.rb', line 190

def at_least_one_of(*keys)
  validate([:at_least_one_of, keys]) do |h|
    count = h.keys.count { |k| keys.include?(k) }
    count > 0
  end
end

#booleanObject



174
175
176
# File 'lib/composable_validations.rb', line 174

def boolean
  inclusion([true, false])
end

#date_string(format = /\A\d\d\d\d-\d\d-\d\d\Z/, msg = [:date_string, 'YYYY-MM-DD']) ⇒ Object



132
133
134
# File 'lib/composable_validations.rb', line 132

def date_string(format = /\A\d\d\d\d-\d\d-\d\d\Z/, msg = [:date_string, 'YYYY-MM-DD'])
  guarded_parsing(format, msg) { |v| Date.parse(v) }
end

#each(validator) ⇒ Object



27
28
29
# File 'lib/composable_validations.rb', line 27

def each(validator)
  each_in_slice(0..-1, validator)
end

#each_in_slice(range, validator) ⇒ Object



31
32
33
34
35
36
37
38
39
40
# File 'lib/composable_validations.rb', line 31

def each_in_slice(range, validator)
  lambda do |a, errors, prefix|
    slice = a.slice(range) || []
    slice.inject([true, 0]) do |(acc, index), elem|
      suffix = to_index(a, range.begin) + index
      b = validator.call(elem, errors, join(prefix, suffix))
      [acc && b, index + 1]
    end.first
  end
end

#exact_size(n, msg = [:exact_size, n]) ⇒ Object



211
212
213
# File 'lib/composable_validations.rb', line 211

def exact_size(n, msg = [:exact_size, n])
  size(equal(n, msg))
end

#float(msg = :float) ⇒ Object



104
105
106
# File 'lib/composable_validations.rb', line 104

def float(msg = :float)
  just_types(msg, Float, Fixnum)
end

#format(regex, msg = :format) ⇒ Object



140
141
142
# File 'lib/composable_validations.rb', line 140

def format(regex, msg = :format)
  validate(msg) { |val| regex.match(val) }
end

#guarded_parsing(format, msg, &blk) ⇒ Object



144
145
146
147
148
149
# File 'lib/composable_validations.rb', line 144

def guarded_parsing(format, msg, &blk)
  fail_fast(
    string(msg),
    format(format, msg),
    parsing(msg, &blk))
end

#inclusion(options, msg = [:inclusion, options]) ⇒ Object



178
179
180
# File 'lib/composable_validations.rb', line 178

def inclusion(options, msg = [:inclusion,  options])
  validate(msg) { |v| options.include?(v) }
end

#integer(msg = :integer) ⇒ Object



96
97
98
# File 'lib/composable_validations.rb', line 96

def integer(msg = :integer)
  just_type(Fixnum, msg)
end

#just_array(msg = :just_array) ⇒ Object



82
83
84
# File 'lib/composable_validations.rb', line 82

def just_array(msg = :just_array)
  just_type(Array, msg)
end

#just_hash(msg = :just_hash) ⇒ Object



78
79
80
# File 'lib/composable_validations.rb', line 78

def just_hash(msg = :just_hash)
  just_type(Hash, msg)
end

#just_type(type, msg) ⇒ Object



162
163
164
# File 'lib/composable_validations.rb', line 162

def just_type(type, msg)
  just_types(msg, type)
end

#just_types(msg, *types) ⇒ Object



166
167
168
169
170
171
172
# File 'lib/composable_validations.rb', line 166

def just_types(msg, *types)
  validate(msg) do |v|
    types.inject(false) do |acc, type|
      acc || v.is_a?(type)
    end
  end
end

#key(key, *validators) ⇒ Object



59
60
61
62
63
64
65
66
# File 'lib/composable_validations.rb', line 59

def key(key, *validators)
  fail_fast(
    presence_of_key(key),
    lambda do |h, errors, prefix|
      run_all(*validators).call(h[key], errors, join(prefix, key))
    end
  )
end

#max_size(n, msg = [:max_size, n]) ⇒ Object



207
208
209
# File 'lib/composable_validations.rb', line 207

def max_size(n, msg = [:max_size, n])
  size(less_or_equal(n, msg))
end

#min_size(n, msg = [:min_size, n]) ⇒ Object



203
204
205
# File 'lib/composable_validations.rb', line 203

def min_size(n, msg = [:min_size, n])
  size(greater_or_equal(n, msg))
end

#non_empty(msg = :non_empty) ⇒ Object



186
187
188
# File 'lib/composable_validations.rb', line 186

def non_empty(msg = :non_empty)
  validate(msg) { |v| !v.empty? }
end

#non_empty_string(msg = :non_empty_string) ⇒ Object



90
91
92
93
94
# File 'lib/composable_validations.rb', line 90

def non_empty_string(msg = :non_empty_string)
  fail_fast(
    string,
    validate(msg) { |s| s.strip != '' })
end

#non_negative(msg = :non_negative) ⇒ Object



128
129
130
# File 'lib/composable_validations.rb', line 128

def non_negative(msg = :non_negative)
  validate(msg) { |v| Float(v.to_s) >= 0 }
end

#non_negative_floatObject



112
113
114
# File 'lib/composable_validations.rb', line 112

def non_negative_float
  fail_fast(float, non_negative)
end

#non_negative_integerObject



116
117
118
# File 'lib/composable_validations.rb', line 116

def non_negative_integer
  fail_fast(integer, non_negative)
end

#non_negative_stringy_floatObject



120
121
122
# File 'lib/composable_validations.rb', line 120

def non_negative_stringy_float
  fail_fast(stringy_float, non_negative)
end

#non_negative_stringy_integerObject



124
125
126
# File 'lib/composable_validations.rb', line 124

def non_negative_stringy_integer
  fail_fast(stringy_integer, non_negative)
end

#optional_key(key, *validators) ⇒ Object



68
69
70
71
72
73
74
75
76
# File 'lib/composable_validations.rb', line 68

def optional_key(key, *validators)
  lambda do |h, errors, prefix|
    if h.has_key?(key)
      key(key, *validators).call(h, errors, prefix)
    else
      true
    end
  end
end

#parsing(msg, &blk) ⇒ Object



151
152
153
154
155
156
157
158
159
160
# File 'lib/composable_validations.rb', line 151

def parsing(msg, &blk)
  validate(msg) do |val|
    begin
      yield(val)
      true
    rescue ArgumentError, TypeError
      false
    end
  end
end

#presence_of_key(key, msg = :presence_of_key) ⇒ Object



182
183
184
# File 'lib/composable_validations.rb', line 182

def presence_of_key(key, msg = :presence_of_key)
  validate(:presence_of_key, key) { |h| h.has_key?(key) }
end

#size(validator) ⇒ Object



197
198
199
200
201
# File 'lib/composable_validations.rb', line 197

def size(validator)
  lambda do |object, errors, path|
    validator.call(object.size, errors, path)
  end
end

#size_range(range, msg = [:size_range, range]) ⇒ Object



215
216
217
# File 'lib/composable_validations.rb', line 215

def size_range(range, msg = [:size_range, range])
  size(in_range(range, msg))
end

#string(msg = :string) ⇒ Object



86
87
88
# File 'lib/composable_validations.rb', line 86

def string(msg = :string)
  just_type(String, msg)
end

#stringy_float(msg = :stringy_float) ⇒ Object



108
109
110
# File 'lib/composable_validations.rb', line 108

def stringy_float(msg = :stringy_float)
  parsing(msg) { |v| Float(v.to_s) }
end

#stringy_integer(msg = :stringy_integer) ⇒ Object



100
101
102
# File 'lib/composable_validations.rb', line 100

def stringy_integer(msg = :stringy_integer)
  parsing(msg) { |v| Integer(v.to_s) }
end

#time_string(format = //, msg = :time_string) ⇒ Object



136
137
138
# File 'lib/composable_validations.rb', line 136

def time_string(format = //, msg = :time_string)
  guarded_parsing(format, msg) { |v| Time.parse(v) }
end

#to_index(array, range_index) ⇒ Object



42
43
44
45
# File 'lib/composable_validations.rb', line 42

def to_index(array, range_index)
  indexes = array.map.with_index { |_, i| i }
  indexes[range_index]
end