rschema 2.4.0 → 3.0.1.pre1

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.
@@ -0,0 +1,60 @@
1
+ module RSchema
2
+ module Schemas
3
+ class FixedLengthArray
4
+ attr_reader :subschemas
5
+
6
+ def initialize(subschemas)
7
+ @subschemas = subschemas
8
+ end
9
+
10
+ def call(value, options=RSchema::Options.default)
11
+ unless value.kind_of?(Array)
12
+ return Result.failure(Error.new(
13
+ symbolic_name: :not_an_array,
14
+ schema: self,
15
+ value: value,
16
+ ))
17
+ end
18
+
19
+ unless value.size == @subschemas.size
20
+ return Result.failure(Error.new(
21
+ symbolic_name: :incorrect_size,
22
+ schema: self,
23
+ value: value,
24
+ ))
25
+ end
26
+
27
+ validate_value, error = apply_subschemas(value, options)
28
+ if error.empty?
29
+ Result.success(validate_value)
30
+ else
31
+ Result.failure(error)
32
+ end
33
+ end
34
+
35
+ def with_wrapped_subschemas(wrapper)
36
+ wrapped_subschemas = subschemas.map{ |ss| wrapper.wrap(ss) }
37
+ self.class.new(wrapped_subschemas)
38
+ end
39
+
40
+ private
41
+
42
+ def apply_subschemas(array_value, options)
43
+ validate_value = []
44
+ errors = {}
45
+
46
+ array_value.zip(@subschemas).each_with_index do |(subvalue, subschema), idx|
47
+ result = subschema.call(subvalue, options)
48
+ if result.valid?
49
+ validate_value << result.value
50
+ else
51
+ errors[idx] = result.error
52
+ break if options.fail_fast?
53
+ end
54
+ end
55
+
56
+ [validate_value, errors]
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,23 @@
1
+ module RSchema
2
+ module Schemas
3
+ class Maybe
4
+ attr_reader :subschema
5
+
6
+ def initialize(subschema)
7
+ @subschema = subschema
8
+ end
9
+
10
+ def call(value, options=Options.default)
11
+ if value == nil
12
+ Result.success(value)
13
+ else
14
+ @subschema.call(value, options)
15
+ end
16
+ end
17
+
18
+ def with_wrapped_subschemas(wrapper)
19
+ self.class.new(wrapper.wrap(subschema))
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ module RSchema
2
+ module Schemas
3
+ class Pipeline
4
+ attr_reader :subschemas
5
+
6
+ def initialize(subschemas)
7
+ @subschemas = subschemas
8
+ end
9
+
10
+ def call(value, options=Options.default)
11
+ result = Result.success(value)
12
+
13
+ subschemas.each do |subsch|
14
+ result = subsch.call(result.value, options)
15
+ break if result.invalid?
16
+ end
17
+
18
+ result
19
+ end
20
+
21
+ def with_wrapped_subschemas(wrapper)
22
+ wrapped_subschemas = subschemas.map{ |ss| wrapper.wrap(ss) }
23
+ self.class.new(wrapped_subschemas)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ module RSchema
2
+ module Schemas
3
+ class Predicate
4
+ attr_reader :block
5
+
6
+ def initialize(block)
7
+ @block = block
8
+ end
9
+
10
+ def call(value, options=Options.default)
11
+ if block.call(value)
12
+ Result.success(value)
13
+ else
14
+ Result.failure(Error.new(
15
+ schema: self,
16
+ value: value,
17
+ symbolic_name: :false,
18
+ ))
19
+ end
20
+ end
21
+
22
+ def with_wrapped_subschemas(wrapper)
23
+ self
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,56 @@
1
+ require 'set'
2
+
3
+ module RSchema
4
+ module Schemas
5
+ class Set
6
+ attr_reader :subschema
7
+
8
+ def initialize(subschema)
9
+ @subschema = subschema
10
+ end
11
+
12
+ def call(value, options=RSchema::Options.default)
13
+ return not_a_set_result(value) unless value.is_a?(::Set)
14
+
15
+ result_value = ::Set.new
16
+ result_errors = []
17
+
18
+ value.each do |subvalue|
19
+ subresult = subschema.call(subvalue, options)
20
+ if subresult.valid?
21
+ result_value << subresult.value
22
+ else
23
+ result_errors << subresult.error
24
+ end
25
+
26
+ break if options.fail_fast?
27
+ end
28
+
29
+ if result_errors.empty?
30
+ Result.success(result_value)
31
+ else
32
+ Result.failure(Error.new(
33
+ schema: self,
34
+ value: value,
35
+ symbolic_name: :contents_invalid,
36
+ vars: result_errors,
37
+ ))
38
+ end
39
+ end
40
+
41
+ def with_wrapped_subschemas(wrapper)
42
+ wrapped_subschema = wrapper.wrap(subschema)
43
+ self.class.new(wrapped_subschema)
44
+ end
45
+
46
+ private
47
+ def not_a_set_result(value)
48
+ Result.failure(Error.new(
49
+ schema: self,
50
+ symbolic_name: :not_a_set,
51
+ value: value,
52
+ ))
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,36 @@
1
+ module RSchema
2
+ module Schemas
3
+ class Sum
4
+ attr_reader :subschemas
5
+
6
+ def initialize(subschemas)
7
+ @subschemas = subschemas
8
+ end
9
+
10
+ def call(value, options=Options.default)
11
+ suberrors = []
12
+
13
+ @subschemas.each do |subsch|
14
+ result = subsch.call(value, options)
15
+ if result.valid?
16
+ return result
17
+ else
18
+ suberrors << result.error
19
+ end
20
+ end
21
+
22
+ Result.failure(Error.new(
23
+ schema: self,
24
+ value: value,
25
+ symbolic_name: :all_invalid,
26
+ vars: suberrors,
27
+ ))
28
+ end
29
+
30
+ def with_wrapped_subschemas(wrapper)
31
+ wrapped_subschemas = subschemas.map{ |ss| wrapper.wrap(ss) }
32
+ self.class.new(wrapped_subschemas)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ module RSchema
2
+ module Schemas
3
+ class Type
4
+ attr_reader :type
5
+
6
+ def initialize(type)
7
+ @type = type
8
+ end
9
+
10
+ def call(value, options = RSchema::Options.default)
11
+ if value.is_a?(@type)
12
+ Result.success(value)
13
+ else
14
+ Result.failure(Error.new(
15
+ schema: self,
16
+ value: value,
17
+ symbolic_name: :wrong_type,
18
+ ))
19
+ end
20
+ end
21
+
22
+ def with_wrapped_subschemas(wrapper)
23
+ self
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,67 @@
1
+ module RSchema
2
+ module Schemas
3
+ class VariableHash
4
+ attr_reader :key_schema, :value_schema
5
+
6
+ def initialize(key_schema, value_schema)
7
+ @key_schema = key_schema
8
+ @value_schema = value_schema
9
+ end
10
+
11
+ def call(value, options=Options.default)
12
+ return not_a_hash_result(value) unless value.is_a?(Hash)
13
+
14
+ result, key_errors, value_errors = apply_subschemas(value, options)
15
+
16
+ if key_errors.empty? && value_errors.empty?
17
+ Result.success(result)
18
+ else
19
+ Result.failure(keys: key_errors, values: value_errors)
20
+ end
21
+ end
22
+
23
+ def with_wrapped_subschemas(wrapper)
24
+ self.class.new(
25
+ wrapper.wrap(key_schema),
26
+ wrapper.wrap(value_schema),
27
+ )
28
+ end
29
+
30
+ private
31
+
32
+ def not_a_hash_result(value)
33
+ Result.failure(Error.new(
34
+ schema: self,
35
+ value: value,
36
+ symbolic_name: :not_a_hash,
37
+ ))
38
+ end
39
+
40
+ def apply_subschemas(value, options)
41
+ result = {}
42
+ key_errors = {}
43
+ value_errors = {}
44
+
45
+ value.each do |key, subvalue|
46
+ key_result = key_schema.call(key, options)
47
+ if key_result.invalid?
48
+ key_errors[key] = key_result.error
49
+ break if options.fail_fast?
50
+ end
51
+
52
+ subvalue_result = value_schema.call(subvalue, options)
53
+ if subvalue_result.invalid?
54
+ value_errors[key] = subvalue_result.error
55
+ break if options.fail_fast?
56
+ end
57
+
58
+ if key_result.valid? && subvalue_result.valid?
59
+ result[key_result.value] = subvalue_result.value
60
+ end
61
+ end
62
+
63
+ return result, key_errors, value_errors
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,49 @@
1
+ module RSchema
2
+ module Schemas
3
+ class VariableLengthArray
4
+ attr_accessor :element_schema
5
+
6
+ def initialize(element_schema)
7
+ @element_schema = element_schema
8
+ end
9
+
10
+ def call(value, options = RSchema::Options.default)
11
+ if value.kind_of?(Array)
12
+ validated_values, errors = validate_elements(value, options)
13
+ if errors.empty?
14
+ Result.success(validated_values)
15
+ else
16
+ Result.failure(errors)
17
+ end
18
+ else
19
+ Result.failure(Error.new(
20
+ schema: self,
21
+ value: value,
22
+ symbolic_name: :not_an_array,
23
+ ))
24
+ end
25
+ end
26
+
27
+ def with_wrapped_subschemas(wrapper)
28
+ self.class.new(wrapper.wrap(element_schema))
29
+ end
30
+
31
+ def validate_elements(array, options)
32
+ errors = {}
33
+ validated_values = []
34
+
35
+ array.each_with_index do |subvalue, idx|
36
+ result = @element_schema.call(subvalue, options)
37
+ if result.valid?
38
+ validated_values[idx] = result.value
39
+ else
40
+ errors[idx] = result.error
41
+ break if options.fail_fast?
42
+ end
43
+ end
44
+
45
+ [validated_values, errors]
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,3 +1,3 @@
1
1
  module RSchema
2
- VERSION = '2.4.0'
2
+ VERSION = '3.0.1.pre1'
3
3
  end
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: 2.4.0
4
+ version: 3.0.1.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Dalling
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-07 00:00:00.000000000 Z
11
+ date: 2017-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -67,8 +67,8 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  description: |2
70
- Schema-based validation and coercion for Ruby data structures. Heavily inspired
71
- by (read: stolen from) Prismatic/schema for Clojure.
70
+ Schema-based validation and coercion for Ruby data structures, inspired
71
+ by Prismatic/schema for Clojure.
72
72
  email:
73
73
  - tom@tomdalling.com
74
74
  executables: []
@@ -78,11 +78,28 @@ files:
78
78
  - LICENSE.txt
79
79
  - README.md
80
80
  - lib/rschema.rb
81
- - lib/rschema/rails_interop.rb
81
+ - lib/rschema/dsl.rb
82
+ - lib/rschema/error.rb
83
+ - lib/rschema/http_coercer.rb
84
+ - lib/rschema/options.rb
85
+ - lib/rschema/result.rb
86
+ - lib/rschema/schemas/anything.rb
87
+ - lib/rschema/schemas/boolean.rb
88
+ - lib/rschema/schemas/enum.rb
89
+ - lib/rschema/schemas/fixed_hash.rb
90
+ - lib/rschema/schemas/fixed_length_array.rb
91
+ - lib/rschema/schemas/maybe.rb
92
+ - lib/rschema/schemas/pipeline.rb
93
+ - lib/rschema/schemas/predicate.rb
94
+ - lib/rschema/schemas/set.rb
95
+ - lib/rschema/schemas/sum.rb
96
+ - lib/rschema/schemas/type.rb
97
+ - lib/rschema/schemas/variable_hash.rb
98
+ - lib/rschema/schemas/variable_length_array.rb
82
99
  - lib/rschema/version.rb
83
- homepage: http://www.tomdalling.com/rschema
100
+ homepage: https://github.com/tomdalling/rschema
84
101
  licenses:
85
- - MIT
102
+ - Apache-2.0
86
103
  metadata: {}
87
104
  post_install_message:
88
105
  rdoc_options: []
@@ -95,12 +112,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
95
112
  version: 2.0.0
96
113
  required_rubygems_version: !ruby/object:Gem::Requirement
97
114
  requirements:
98
- - - ">="
115
+ - - ">"
99
116
  - !ruby/object:Gem::Version
100
- version: '0'
117
+ version: 1.3.1
101
118
  requirements: []
102
119
  rubyforge_project:
103
- rubygems_version: 2.5.1
120
+ rubygems_version: 2.4.5
104
121
  signing_key:
105
122
  specification_version: 4
106
123
  summary: Schema-based validation and coercion for Ruby data structures