rschema 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/rschema.rb +35 -20
- data/lib/rschema/version.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a5600f4f1f9cbe2d7743bd360a7005fa6b01da7
|
4
|
+
data.tar.gz: af415074e5917d934775f1d1c96b9afea39539f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6683829451d8153d46d7e66aac10939a27191ba47664103b8f33d35f937298755325d389857c1df065d0a0b3f7658825ef33a02d2a1d4da096d42f9df4ec62c6
|
7
|
+
data.tar.gz: 164aaf435884ae2fdbd6ffc84c779dbb922a328527b1e392316934bde24cfedfed272cf35d3505d2241bf3d4256da6261ae2444bc96d75dc00847b9b12715708
|
data/lib/rschema.rb
CHANGED
@@ -4,16 +4,27 @@ module RSchema
|
|
4
4
|
InvalidSchemaError = Class.new(StandardError)
|
5
5
|
ValidationError = Class.new(StandardError)
|
6
6
|
OptionalHashKey = Struct.new(:key)
|
7
|
-
ErrorDetails = Struct.new(:
|
8
|
-
def
|
9
|
-
|
7
|
+
ErrorDetails = Struct.new(:failing_value, :reason, :key_path) do
|
8
|
+
def initialize(failing_value, reason, key_path = [])
|
9
|
+
super(failing_value, reason, key_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
prefix = (key_path.empty? ? 'The root value' : "The value at #{key_path.inspect}")
|
14
|
+
"#{prefix} #{reason}: #{failing_value.inspect}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def extend_key_path(key)
|
18
|
+
key_path.unshift(key)
|
19
|
+
self
|
20
|
+
end
|
10
21
|
end
|
11
22
|
|
12
23
|
def self.schema(&block)
|
13
24
|
DSL.instance_exec(&block)
|
14
25
|
end
|
15
26
|
|
16
|
-
def self.
|
27
|
+
def self.validation_error(schema, value)
|
17
28
|
_, error = walk(schema, value)
|
18
29
|
error
|
19
30
|
end
|
@@ -27,6 +38,10 @@ module RSchema
|
|
27
38
|
end
|
28
39
|
end
|
29
40
|
|
41
|
+
def self.validate(schema, value)
|
42
|
+
validation_error(schema, value).nil?
|
43
|
+
end
|
44
|
+
|
30
45
|
def self.coerce(schema, value)
|
31
46
|
walk(schema, value, CoercionMapper)
|
32
47
|
end
|
@@ -141,17 +156,17 @@ module RSchema
|
|
141
156
|
GenericHashSchema = Struct.new(:key_subschema, :value_subschema) do
|
142
157
|
def schema_walk(value, mapper)
|
143
158
|
if not value.is_a?(Hash)
|
144
|
-
return RSchema::ErrorDetails.new('is not a Hash')
|
159
|
+
return RSchema::ErrorDetails.new(value, 'is not a Hash')
|
145
160
|
end
|
146
161
|
|
147
162
|
value.reduce({}) do |accum, (k, v)|
|
148
163
|
# walk key
|
149
164
|
k_walked, error = RSchema.walk(key_subschema, k, mapper)
|
150
|
-
break
|
165
|
+
break error.extend_key_path('.keys') if error
|
151
166
|
|
152
167
|
# walk value
|
153
168
|
v_walked, error = RSchema.walk(value_subschema, v, mapper)
|
154
|
-
break
|
169
|
+
break error.extend_key_path(k) if error
|
155
170
|
|
156
171
|
accum[k_walked] = v_walked
|
157
172
|
accum
|
@@ -161,11 +176,11 @@ module RSchema
|
|
161
176
|
|
162
177
|
GenericSetSchema = Struct.new(:subschema) do
|
163
178
|
def schema_walk(value, mapper)
|
164
|
-
return RSchema::ErrorDetails.new('is not a Set') if not value.is_a?(Set)
|
179
|
+
return RSchema::ErrorDetails.new(value, 'is not a Set') if not value.is_a?(Set)
|
165
180
|
|
166
181
|
value.reduce(Set.new) do |accum, subvalue|
|
167
182
|
subvalue_walked, error = RSchema.walk(subschema, subvalue, mapper)
|
168
|
-
break
|
183
|
+
break error.extend_key_path('.values') if error
|
169
184
|
|
170
185
|
accum << subvalue_walked
|
171
186
|
accum
|
@@ -178,7 +193,7 @@ module RSchema
|
|
178
193
|
if block.call(value)
|
179
194
|
value
|
180
195
|
else
|
181
|
-
RSchema::ErrorDetails.new('fails predicate' + (name ? ": #{name}" : ''))
|
196
|
+
RSchema::ErrorDetails.new(value, 'fails predicate' + (name ? ": #{name}" : ''))
|
182
197
|
end
|
183
198
|
end
|
184
199
|
end
|
@@ -207,7 +222,7 @@ module RSchema
|
|
207
222
|
if value_set.include?(value_walked)
|
208
223
|
value_walked
|
209
224
|
else
|
210
|
-
RSchema::ErrorDetails.new("#{value_walked} is not a valid enum member")
|
225
|
+
RSchema::ErrorDetails.new(value_walked, "#{value_walked} is not a valid enum member")
|
211
226
|
end
|
212
227
|
end
|
213
228
|
end
|
@@ -217,7 +232,7 @@ module RSchema
|
|
217
232
|
if value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
218
233
|
value
|
219
234
|
else
|
220
|
-
RSchema::ErrorDetails.new('is not a boolean')
|
235
|
+
RSchema::ErrorDetails.new(value, 'is not a boolean')
|
221
236
|
end
|
222
237
|
end
|
223
238
|
end
|
@@ -228,7 +243,7 @@ class Class
|
|
228
243
|
if value.is_a?(self)
|
229
244
|
value
|
230
245
|
else
|
231
|
-
RSchema::ErrorDetails.new("is not a #{self.name}, is a #{value.class.name}")
|
246
|
+
RSchema::ErrorDetails.new(value, "is not a #{self.name}, is a #{value.class.name}")
|
232
247
|
end
|
233
248
|
end
|
234
249
|
end
|
@@ -238,14 +253,14 @@ class Array
|
|
238
253
|
fixed_size = (size != 1)
|
239
254
|
|
240
255
|
if not value.is_a?(Array)
|
241
|
-
RSchema::ErrorDetails.new(
|
256
|
+
RSchema::ErrorDetails.new(value, 'is not an Array')
|
242
257
|
elsif fixed_size && value.size != size
|
243
|
-
RSchema::ErrorDetails.new("does not have #{size} elements")
|
258
|
+
RSchema::ErrorDetails.new(value, "does not have #{size} elements")
|
244
259
|
else
|
245
260
|
value.each.with_index.map do |subvalue, idx|
|
246
261
|
subschema = (fixed_size ? self[idx] : first)
|
247
262
|
subvalue_walked, error = RSchema.walk(subschema, subvalue, mapper)
|
248
|
-
break
|
263
|
+
break error.extend_key_path(idx) if error
|
249
264
|
subvalue_walked
|
250
265
|
end
|
251
266
|
end
|
@@ -254,7 +269,7 @@ end
|
|
254
269
|
|
255
270
|
class Hash
|
256
271
|
def schema_walk(value, mapper)
|
257
|
-
return RSchema::ErrorDetails.new('is not a Hash') if not value.is_a?(Hash)
|
272
|
+
return RSchema::ErrorDetails.new(value, 'is not a Hash') if not value.is_a?(Hash)
|
258
273
|
|
259
274
|
# extract details from the schema
|
260
275
|
required_keys = Set.new
|
@@ -271,19 +286,19 @@ class Hash
|
|
271
286
|
# check for extra keys that shouldn't be there
|
272
287
|
extraneous = value.keys.reject{ |k| all_subschemas.has_key?(k) }
|
273
288
|
if extraneous.size > 0
|
274
|
-
return RSchema::ErrorDetails.new(
|
289
|
+
return RSchema::ErrorDetails.new(value, "has extraneous keys: #{extraneous.inspect}")
|
275
290
|
end
|
276
291
|
|
277
292
|
# check for required keys that are missing
|
278
293
|
missing_requireds = required_keys.reject{ |k| value.has_key?(k) }
|
279
294
|
if missing_requireds.size > 0
|
280
|
-
return RSchema::ErrorDetails.new(
|
295
|
+
return RSchema::ErrorDetails.new(value, "is missing required keys: #{missing_requireds.inspect}")
|
281
296
|
end
|
282
297
|
|
283
298
|
# walk the subvalues
|
284
299
|
value.reduce({}) do |accum, (k, subvalue)|
|
285
300
|
subvalue_walked, error = RSchema.walk(all_subschemas[k], subvalue, mapper)
|
286
|
-
break
|
301
|
+
break error.extend_key_path(k) if error
|
287
302
|
accum[k] = subvalue_walked
|
288
303
|
accum
|
289
304
|
end
|
data/lib/rschema/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rschema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Dalling
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: gem-release
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.7'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: pry
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -54,7 +68,7 @@ dependencies:
|
|
54
68
|
version: '0'
|
55
69
|
description: |2
|
56
70
|
Schema-based validation and coercion for Ruby data structures. Heavily inspired
|
57
|
-
by (read: stolen from)
|
71
|
+
by (read: stolen from) Prismatic/schema for Clojure.
|
58
72
|
email:
|
59
73
|
- tom@tomdalling.com
|
60
74
|
executables: []
|