datacaster 3.1.0 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c42f42112214378de25b126640a7bb578532c1db0ac9fbb73914ef3c08db76e2
4
- data.tar.gz: 0abba877a155d717b0aa2cb605c9214789c839b381492984cb277a1523c5a7a1
3
+ metadata.gz: 22f1741420c172f91fba9bf20a341a785f609a7e0132e74bcd3a07e6069eaca4
4
+ data.tar.gz: 641fb863b7a40931f481d066e09062cddff1a4e3ff642d5981dacf9bfaa036eb
5
5
  SHA512:
6
- metadata.gz: 4b07733981e971af666cf9a7688cd35f4a32b80eb2e4a53505620425027f5fdd963c7c63717f6888fe700df4ef6c5eb175a07aac7183cb0df29dd1e8b97fe446
7
- data.tar.gz: a596b40d1ebff4e8abc455bdde09c01b0f1499a35cee44daca329885277448cbe6f66268d568a091fa78e83e0da7adf9d9cb09df0c5711d4bc3243d3b909a886
6
+ metadata.gz: 2a3573aac6a44ef0a5849da04325c9089119ad529cc6f6384d18bb6dda97f66358081c27d1fc260d95f7adaec5937bda7769cd9207ea9be6b01f2547f4425659
7
+ data.tar.gz: '04765854fbe156b3418728d4d2392b78ce0837ead8e1e72b76a51d55e6227bb68eebf8a98e672c924205bbe731610f21c72a1be355c51c2f014886ab160efdb7'
data/README.md CHANGED
@@ -32,12 +32,12 @@ It is currently used in production in several projects (mainly as request parame
32
32
  - [`integer32(error_key = nil)`](#integer32error_key--nil)
33
33
  - [`non_empty_string(error_key = nil)`](#non_empty_stringerror_key--nil)
34
34
  - [Special types](#special-types)
35
- - [`absent(error_key = nil)`](#absenterror_key--nil)
35
+ - [`absent(error_key = nil, on: nil)`](#absenterror_key--nil-on-nil)
36
36
  - [`any(error_key = nil)`](#anyerror_key--nil)
37
37
  - [`default(default_value, on: nil)`](#defaultdefault_value-on-nil)
38
38
  - [`merge_message_keys(*keys)`](#merge_message_keyskeys)
39
39
  - [`must_be(klass, error_key = nil)`](#must_beklass-error_key--nil)
40
- - [`optional(base)`](#optionalbase)
40
+ - [`optional(base, on: nil)`](#optionalbase-on-nil)
41
41
  - [`pass`](#pass)
42
42
  - [`pass_if(base)`](#pass_ifbase)
43
43
  - [`pick(key)`](#pickkey)
@@ -56,6 +56,8 @@ It is currently used in production in several projects (mainly as request parame
56
56
  - [`try(error_key = nil, catched_exception:) { |value| ... }`](#tryerror_key--nil-catched_exception--value--)
57
57
  - [`validate(active_model_validations, name = 'Anonymous')`](#validateactive_model_validations-name--anonymous)
58
58
  - [`compare(reference_value, error_key = nil)`](#comparereference_value-error_key--nil)
59
+ - [`included_in(*reference_values, error_key: nil)`](#included_inreference_values-error_key-nil)
60
+ - [`relate(left, op, right, error_key: nil)`](#relateleft-op-right-error_key-nil)
59
61
  - [`transform { |value| ... }`](#transform--value--)
60
62
  - [`transform_if_present { |value| ... }`](#transform_if_present--value--)
61
63
  - [Array schemas](#array-schemas)
@@ -175,10 +177,10 @@ array = Datacaster.schema { array }
175
177
  array.(nil)
176
178
 
177
179
  # In this README
178
- #=> Datacaster::ErrorResult(['should be an array'])
180
+ # => Datacaster::ErrorResult(['should be an array'])
179
181
 
180
182
  # In reality
181
- #=> <Datacaster::ErrorResult([#<Datacaster::I18nValues::Key(.array, datacaster.errors.array) {:value=>nil}>])>
183
+ # => <Datacaster::ErrorResult([#<Datacaster::I18nValues::Key(.array, datacaster.errors.array) {:value=>nil}>])>
182
184
  ```
183
185
 
184
186
  See [section on i18n](#internationalization-i18n) for details.
@@ -502,9 +504,16 @@ Returns ValidResult if and only if provided value is a string and is not empty.
502
504
 
503
505
  ### Special types
504
506
 
505
- #### `absent(error_key = nil)`
507
+ #### `absent(error_key = nil, on: nil)`
506
508
 
507
- Returns ValidResult if and only if provided value is `Datacaster.absent` (this is singleton instance). Relevant only for hash schemas (see below). Doesn't transform the value.
509
+ Returns ValidResult if and only if provided value is absent. Relevant only for hash schemas (see below). Transforms the value to `Datacaster.absent`.
510
+
511
+ The value is considered absent:
512
+
513
+ * if the value is `Datacaster.absent` (`on` is disregarded in such case)
514
+ * if `on` is set to a method name to which the value responds and yields truthy
515
+
516
+ Set `on` to `:nil?`, `:empty?` or similar method names.
508
517
 
509
518
  I18n keys: `error_key`, `'.absent'`, `'datacaster.errors.absent'`.
510
519
 
@@ -636,18 +645,25 @@ Returns ValidResult if and only if the value `#is_a?(klass)`. Doesn't transform
636
645
 
637
646
  I18n keys: `error_key`, `'.must_be'`, `'datacaster.errors.must_be'`. Adds `reference` i18n variable, setting it to `klass.name`.
638
647
 
639
- #### `optional(base)`
648
+ #### `optional(base, on: nil)`
640
649
 
641
- Returns ValidResult if and only if the value is either `Datacaster.absent` or passes `base` validation. See below documentation on hash schemas for details on `Datacaster.absent`.
650
+ Returns ValidResult if and only if the value is either absent or passes `base` validation. In the value is absent, transforms it to the `Datacaster.absent`. Otherwise, returns `base` result.
651
+
652
+ Value is considered absent:
653
+
654
+ * if the value is `Datacaster.absent` (`on` is disregarded in such case)
655
+ * if `on` is set to a method name to which the value responds and yields truthy
656
+
657
+ Set `on` to `:nil?`, `:empty?` or similar method names.
642
658
 
643
659
  ```ruby
644
660
  item_with_optional_price =
645
- Datacaster.schema do
646
- hash_schema(
647
- name: string,
648
- price: optional(float)
649
- )
650
- end
661
+ Datacaster.schema do
662
+ hash_schema(
663
+ name: string,
664
+ price: optional(float)
665
+ )
666
+ end
651
667
 
652
668
  item_with_optional_price.(name: "Book", price: 1.23)
653
669
  # => Datacaster::ValidResult({:name=>"Book", :price=>1.23})
@@ -868,8 +884,6 @@ I18n is performed by ActiveModel gem.
868
884
 
869
885
  #### `compare(reference_value, error_key = nil)`
870
886
 
871
- This type is the way to ensure some value in your schema is some predefined "constant".
872
-
873
887
  Returns ValidResult if and only if `reference_value` equals value.
874
888
 
875
889
  ```ruby
@@ -883,6 +897,50 @@ agreed_with_tos =
883
897
 
884
898
  I18n keys: `error_key`, `'.compare'`, `'datacaster.errors.compare'`. Adds `reference` i18n variable, setting it to `reference_value.to_s`.
885
899
 
900
+ #### `included_in(*reference_values, error_key: nil)`
901
+
902
+ Returns ValidResult if and only if `reference_values.include?` the value.
903
+
904
+ I18n keys: `error_key`, `'.included_in'`, `'datacaster.errors.included_in'`. Adds `reference` i18n variable, setting it to `reference_values.map(&:to_s).join(', ')`.
905
+
906
+ #### `relate(left, op, right, error_key: nil)`
907
+
908
+ Returns ValidResult if and only if `left`, `right` and `op` returns valid result. Doesn't transform the value.
909
+
910
+ Use `relate` to check relations between object keys:
911
+
912
+ ```ruby
913
+ ordered =
914
+ # Check that hash[:a] < hash[:b]
915
+ Datacaster.schema do
916
+ transform_to_hash(
917
+ a: relate(:a, :<, :b) & pick(:a),
918
+ b: pick(:b)
919
+ )
920
+ end
921
+
922
+ ordered.(a: 1, b: 2)
923
+ # => Datacaster::ValidResult({:a=>1, :b=>2})
924
+
925
+ ordered.(a: 2, b: 1)
926
+ # => Datacaster::ErrorResult({:a=>["a should be < b"]})
927
+
928
+ ordered.({})
929
+ # => Datacaster::ErrorResult({:a=>["a should be < b"]})
930
+ ```
931
+
932
+ Notice that shortcut definitions are available (illustrated in the example above) for the `relate` caster:
933
+
934
+ * `:key` provided as 'left' or 'right' argument is exactly the same as `pick(:key)` (works for a string, a symbol or an integer)
935
+ * `:method` provided as 'op' argument is exactly the same as `check { |(l, r)| l.respond_to?(method) && l.public_send(method, r) }` (works for a string or a symbol)
936
+
937
+ Formally, `relate(left, op, right, error_key: error_key)` will:
938
+
939
+ * call the `left` caster with the original value, return the result unless it's valid
940
+ * call the `right` caster with the original value, return the result unless it's valid
941
+ * call the `op` caster with the `[left_result, right_result]`, return the result unless it's valid
942
+ * return the original value as valid result
943
+
886
944
  #### `transform { |value| ... }`
887
945
 
888
946
  Always returns ValidResult. Transforms the value: returns whatever the block has returned.
@@ -1025,7 +1083,7 @@ restricted_params.(username: "test", is_admin: nil)
1025
1083
 
1026
1084
  More practical case is to include `absent` validator in logical expressions, e.g. `something: absent | string`. If `something` is set to `nil`, this validation will fail, which could be the desired (and hardly achieved by any other validation framework) behavior.
1027
1085
 
1028
- Also, see documentation for [`optional(base)`](#optionalbase) and [`optional_param(base)`](#optional_parambase). If some value becomes `Datacaster.absent` in its chain of validations-transformations, it is removed from the resultant hash (on the same stage where the lack of extra/unchecked keys in the hash is validated):
1086
+ Also, see documentation for [`optional(base)`](#optionalbase-on-nil) and [`optional_param(base)`](#optional_parambase). If some value becomes `Datacaster.absent` in its chain of validations-transformations, it is removed from the resultant hash (on the same stage where the lack of extra/unchecked keys in the hash is validated):
1029
1087
 
1030
1088
  ```ruby
1031
1089
  person =
@@ -11,10 +11,12 @@ en:
11
11
  empty: should not be empty
12
12
  float: is not a float
13
13
  hash_value: is not a hash
14
+ included_in: is not one of %{reference}
14
15
  integer: is not an integer
15
16
  integer32: is not a 32-bit integer
16
17
  iso8601: is not a string with ISO-8601 date and time
17
18
  must_be: "is not %{reference}"
19
+ relate: "%{left} should be %{op} %{right}"
18
20
  responds_to: "does not respond to %{reference}"
19
21
  string: is not a string
20
22
  to_boolean: does not look like a boolean
@@ -17,7 +17,7 @@ module Datacaster
17
17
  if right_result.valid?
18
18
  left_result
19
19
  else
20
- Datacaster.ErrorResult(self.class.merge_errors(left_result.raw_errors, right_result.raw_errors))
20
+ Datacaster.ErrorResult(Utils.merge_errors(left_result.raw_errors, right_result.raw_errors))
21
21
  end
22
22
  end
23
23
  end
@@ -1,97 +1,5 @@
1
1
  module Datacaster
2
2
  class Base
3
- def self.merge_errors(left, right)
4
- add_error_to_base = ->(hash, error) {
5
- hash[:base] ||= []
6
- hash[:base] = merge_errors(hash[:base], error)
7
- hash
8
- }
9
-
10
- return [] if left.nil? && right.nil?
11
- return right if left.nil?
12
- return left if right.nil?
13
-
14
- result = case [left.class, right.class]
15
- when [Array, Array]
16
- left | right
17
- when [Array, Hash]
18
- add_error_to_base.(right, left)
19
- when [Hash, Hash]
20
- (left.keys | right.keys).map do |k|
21
- [k, merge_errors(left[k], right[k])]
22
- end.to_h
23
- when [Hash, Array]
24
- add_error_to_base.(left, right)
25
- else
26
- raise ArgumentError.new("Expected failures to be Arrays or Hashes, left: #{left.inspect}, right: #{right.inspect}")
27
- end
28
-
29
- result
30
- end
31
-
32
- def &(other)
33
- AndNode.new(self, other)
34
- end
35
-
36
- def |(other)
37
- OrNode.new(self, other)
38
- end
39
-
40
- def *(other)
41
- AndWithErrorAggregationNode.new(self, other)
42
- end
43
-
44
- def cast_errors(error_caster)
45
- ContextNodes::ErrorsCaster.new(self, error_caster)
46
- end
47
-
48
- def then(other)
49
- ThenNode.new(self, DefinitionDSL.expand(other))
50
- end
51
-
52
- def with_context(context)
53
- unless context.is_a?(Hash)
54
- raise "with_context expected Hash as argument, got #{context.inspect} instead"
55
- end
56
- ContextNodes::UserContext.new(self, context)
57
- end
58
-
59
- def call(object)
60
- call_with_runtime(object, Runtimes::Base.new)
61
- end
62
-
63
- def call_with_runtime(object, runtime)
64
- result = cast(object, runtime: runtime)
65
- unless result.is_a?(Result)
66
- raise RuntimeError.new("Caster should've returned Datacaster::Result, but returned #{result.inspect} instead")
67
- end
68
- result
69
- end
70
-
71
- def with_runtime(runtime)
72
- ->(object) do
73
- call_with_runtime(object, runtime)
74
- end
75
- end
76
-
77
- def i18n_key(*keys, **args)
78
- ContextNodes::I18n.new(self, I18nValues::Key.new(keys, args))
79
- end
80
-
81
- def i18n_map_keys(mapping)
82
- ContextNodes::I18nKeysMapper.new(self, mapping)
83
- end
84
-
85
- def i18n_scope(scope, **args)
86
- ContextNodes::I18n.new(self, I18nValues::Scope.new(scope, args))
87
- end
88
-
89
- def i18n_vars(vars)
90
- ContextNodes::I18n.new(self, I18nValues::Scope.new(nil, vars))
91
- end
92
-
93
- def inspect
94
- "#<Datacaster::Base>"
95
- end
3
+ include Mixin
96
4
  end
97
5
  end
@@ -9,13 +9,13 @@ module Datacaster
9
9
  def cast(object, runtime:)
10
10
  result = Runtimes::Base.(runtime, @cast, object)
11
11
 
12
- raise TypeError.new("Either Datacaster::Result or Dry::Monads::Result " \
13
- "should be returned from cast block") unless [Datacaster::Result, Dry::Monads::Result].any? { |k| result.is_a?(k) }
14
-
15
- if result.is_a?(Dry::Monads::Result)
12
+ if defined?(Dry::Monads::Result) && result.is_a?(Dry::Monads::Result)
16
13
  result = result.success? ? Datacaster.ValidResult(result.value!) : Datacaster.ErrorResult(result.failure)
17
14
  end
18
15
 
16
+ raise TypeError.new("Either Datacaster::Result or Dry::Monads::Result " \
17
+ "should be returned from cast block") unless result.is_a?(Datacaster::Result)
18
+
19
19
  result
20
20
  end
21
21
 
@@ -45,9 +45,9 @@ module Datacaster
45
45
  end
46
46
  else
47
47
  if key.is_a?(Array)
48
- errors = self.class.merge_errors(errors, key.zip(new_value.raw_errors).to_h)
48
+ errors = Utils.merge_errors(errors, key.zip(new_value.raw_errors).to_h)
49
49
  else
50
- errors = self.class.merge_errors(errors, {key => new_value.raw_errors})
50
+ errors = Utils.merge_errors(errors, {key => new_value.raw_errors})
51
51
  end
52
52
  end
53
53
  end
@@ -0,0 +1,68 @@
1
+ module Datacaster
2
+ module Mixin
3
+ def &(other)
4
+ AndNode.new(self, other)
5
+ end
6
+
7
+ def |(other)
8
+ OrNode.new(self, other)
9
+ end
10
+
11
+ def *(other)
12
+ AndWithErrorAggregationNode.new(self, other)
13
+ end
14
+
15
+ def cast_errors(error_caster)
16
+ ContextNodes::ErrorsCaster.new(self, error_caster)
17
+ end
18
+
19
+ def then(other)
20
+ ThenNode.new(self, DefinitionDSL.expand(other))
21
+ end
22
+
23
+ def with_context(context)
24
+ unless context.is_a?(Hash)
25
+ raise "with_context expected Hash as argument, got #{context.inspect} instead"
26
+ end
27
+ ContextNodes::UserContext.new(self, context)
28
+ end
29
+
30
+ def call(object)
31
+ call_with_runtime(object, Runtimes::Base.new)
32
+ end
33
+
34
+ def call_with_runtime(object, runtime)
35
+ result = cast(object, runtime: runtime)
36
+ unless result.is_a?(Result)
37
+ raise RuntimeError.new("Caster should've returned Datacaster::Result, but returned #{result.inspect} instead")
38
+ end
39
+ result
40
+ end
41
+
42
+ def with_runtime(runtime)
43
+ ->(object) do
44
+ call_with_runtime(object, runtime)
45
+ end
46
+ end
47
+
48
+ def i18n_key(*keys, **args)
49
+ ContextNodes::I18n.new(self, I18nValues::Key.new(keys, args))
50
+ end
51
+
52
+ def i18n_map_keys(mapping)
53
+ ContextNodes::I18nKeysMapper.new(self, mapping)
54
+ end
55
+
56
+ def i18n_scope(scope, **args)
57
+ ContextNodes::I18n.new(self, I18nValues::Scope.new(scope, args))
58
+ end
59
+
60
+ def i18n_vars(vars)
61
+ ContextNodes::I18n.new(self, I18nValues::Scope.new(nil, vars))
62
+ end
63
+
64
+ def inspect
65
+ "#<Datacaster::Base>"
66
+ end
67
+ end
68
+ end
@@ -67,10 +67,20 @@ module Datacaster
67
67
 
68
68
  # 'Meta' types
69
69
 
70
- def absent(error_key = nil)
70
+ def absent(error_key = nil, on: nil)
71
71
  error_keys = ['.absent', 'datacaster.errors.absent']
72
72
  error_keys.unshift(error_key) if error_key
73
- check { |x| x == Datacaster.absent }.i18n_key(*error_keys)
73
+
74
+ cast do |x|
75
+ if x == Datacaster.absent ||
76
+ (!on.nil? && x.respond_to?(on) && x.public_send(on))
77
+ Datacaster.ValidResult(Datacaster.absent)
78
+ else
79
+ Datacaster.ErrorResult(
80
+ I18nValues::Key.new(error_keys, value: x)
81
+ )
82
+ end
83
+ end
74
84
  end
75
85
 
76
86
  def any(error_key = nil)
@@ -82,7 +92,7 @@ module Datacaster
82
92
  def default(value, on: nil)
83
93
  transform do |x|
84
94
  if x == Datacaster.absent ||
85
- (on && x.respond_to?(on) && x.public_send(on))
95
+ (!on.nil? && x.respond_to?(on) && x.public_send(on))
86
96
  value
87
97
  else
88
98
  x
@@ -94,6 +104,52 @@ module Datacaster
94
104
  transform { value }
95
105
  end
96
106
 
107
+ # min_amount: has_relation(:min_amount, :>, :max_amount)
108
+
109
+ def relate(left, op, right, error_key: nil)
110
+ error_keys = ['.relate', 'datacaster.errors.relate']
111
+ additional_vars = {}
112
+
113
+ {left: left, op: op, right: right}.each do |k, v|
114
+ if [String, Symbol, Integer].any? { |c| v.is_a?(c) }
115
+ additional_vars[k] = v
116
+ elsif !Datacaster.instance?(v)
117
+ raise RuntimeError, "expected #{k} to be String, Symbol, Integer or Datacaster::Base, but got #{v.inspect}", caller
118
+ end
119
+ end
120
+
121
+ if op.is_a?(Integer)
122
+ raise RuntimeError, "expected op to be String, Symbol or Datacaster::Base, but got #{op.inspect}", caller
123
+ end
124
+
125
+ if [left, op, right].none? { |x| Datacaster.instance?(x) }
126
+ error_keys.unshift(".#{left}.#{op}.#{right}")
127
+ end
128
+ error_keys.unshift(error_key) if error_key
129
+
130
+ left = pick(left) unless Datacaster.instance?(left)
131
+ right = pick(right) unless Datacaster.instance?(right)
132
+ op_caster = op
133
+ unless Datacaster.instance?(op_caster)
134
+ op_caster = check { |(l, r)| l.respond_to?(op) && l.public_send(op, r) }
135
+ end
136
+
137
+ cast do |value|
138
+ left_result = left.(value)
139
+ next left_result unless left_result.valid?
140
+ i18n_var!(:left, left_result.value) unless additional_vars.key?(:left)
141
+
142
+ right_result = right.(value)
143
+ next right_result unless right_result.valid?
144
+ i18n_var!(:right, right_result.value) unless additional_vars.key?(:right)
145
+
146
+ result = op_caster.([left_result.value, right_result.value])
147
+ next Datacaster.ErrorResult([I18nValues::Key.new(error_keys)]) unless result.valid?
148
+
149
+ Datacaster.ValidResult(value)
150
+ end.i18n_vars(additional_vars)
151
+ end
152
+
97
153
  def remove
98
154
  transform { Datacaster.absent }
99
155
  end
@@ -153,8 +209,16 @@ module Datacaster
153
209
  check { |x| x.is_a?(klass) }.i18n_key(*error_keys, reference: klass.name)
154
210
  end
155
211
 
156
- def optional(base)
157
- absent | base
212
+ def optional(base, on: nil)
213
+ return absent | base if on == nil
214
+ cast do |x|
215
+ if x == Datacaster.absent ||
216
+ (!on.nil? && x.respond_to?(on) && x.public_send(on))
217
+ Datacaster.ValidResult(Datacaster.absent)
218
+ else
219
+ base.(x)
220
+ end
221
+ end
158
222
  end
159
223
 
160
224
  # Strict types
@@ -187,13 +251,19 @@ module Datacaster
187
251
  def hash_value(error_key = nil)
188
252
  error_keys = ['.hash_value', 'datacaster.errors.hash_value']
189
253
  error_keys.unshift(error_key) if error_key
190
- check(error_key) { |x| x.is_a?(Hash) }
254
+ check { |x| x.is_a?(Hash) }.i18n_key(*error_keys)
191
255
  end
192
256
 
193
257
  def hash_with_symbolized_keys(error_key = nil)
194
258
  hash_value(error_key) & transform { |x| x.symbolize_keys }
195
259
  end
196
260
 
261
+ def included_in(*values, error_key: nil)
262
+ error_keys = ['.included_in', 'datacaster.errors.included_in']
263
+ error_keys.unshift(error_key) if error_key
264
+ check { |x| values.include?(x) }.i18n_key(*error_keys, reference: values.map(&:to_s).join(', '))
265
+ end
266
+
197
267
  def integer(error_key = nil)
198
268
  error_keys = ['.integer', 'datacaster.errors.integer']
199
269
  error_keys.unshift(error_key) if error_key
@@ -0,0 +1,34 @@
1
+ module Datacaster
2
+ module Utils
3
+ extend self
4
+
5
+ def merge_errors(left, right)
6
+ add_error_to_base = ->(hash, error) {
7
+ hash[:base] ||= []
8
+ hash[:base] = merge_errors(hash[:base], error)
9
+ hash
10
+ }
11
+
12
+ return [] if left.nil? && right.nil?
13
+ return right if left.nil?
14
+ return left if right.nil?
15
+
16
+ result = case [left.class, right.class]
17
+ when [Array, Array]
18
+ left | right
19
+ when [Array, Hash]
20
+ add_error_to_base.(right, left)
21
+ when [Hash, Hash]
22
+ (left.keys | right.keys).map do |k|
23
+ [k, merge_errors(left[k], right[k])]
24
+ end.to_h
25
+ when [Hash, Array]
26
+ add_error_to_base.(left, right)
27
+ else
28
+ raise ArgumentError.new("Expected failures to be Arrays or Hashes, left: #{left.inspect}, right: #{right.inspect}")
29
+ end
30
+
31
+ result
32
+ end
33
+ end
34
+ end
@@ -1,3 +1,3 @@
1
1
  module Datacaster
2
- VERSION = "3.1.0"
2
+ VERSION = "3.1.2"
3
3
  end
data/lib/datacaster.rb CHANGED
@@ -24,6 +24,10 @@ module Datacaster
24
24
  Datacaster::Absent.instance
25
25
  end
26
26
 
27
+ def instance?(object)
28
+ object.is_a?(Mixin)
29
+ end
30
+
27
31
  private
28
32
 
29
33
  def build_schema(i18n_scope: nil, &block)
@@ -31,7 +35,7 @@ module Datacaster
31
35
 
32
36
  datacaster = DefinitionDSL.eval(&block)
33
37
 
34
- unless datacaster.is_a?(Base)
38
+ unless Datacaster.instance?(datacaster)
35
39
  raise "Datacaster instance should be returned from a block (e.g. result of 'hash_schema(...)' call)"
36
40
  end
37
41
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datacaster
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eugene Zolotarev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-02 00:00:00.000000000 Z
11
+ date: 2023-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -150,6 +150,7 @@ files:
150
150
  - lib/datacaster/i18n_values/key.rb
151
151
  - lib/datacaster/i18n_values/scope.rb
152
152
  - lib/datacaster/message_keys_merger.rb
153
+ - lib/datacaster/mixin.rb
153
154
  - lib/datacaster/or_node.rb
154
155
  - lib/datacaster/predefined.rb
155
156
  - lib/datacaster/result.rb
@@ -162,6 +163,7 @@ files:
162
163
  - lib/datacaster/then_node.rb
163
164
  - lib/datacaster/transformer.rb
164
165
  - lib/datacaster/trier.rb
166
+ - lib/datacaster/utils.rb
165
167
  - lib/datacaster/validator.rb
166
168
  - lib/datacaster/version.rb
167
169
  homepage: https://github.com/EugZol/datacaster