dry-schema 1.4.3 → 1.5.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/CHANGELOG.md +170 -97
- data/config/errors.yml +4 -0
- data/dry-schema.gemspec +46 -0
- data/lib/dry-schema.rb +1 -1
- data/lib/dry/schema.rb +19 -6
- data/lib/dry/schema/compiler.rb +4 -4
- data/lib/dry/schema/config.rb +15 -6
- data/lib/dry/schema/constants.rb +16 -7
- data/lib/dry/schema/dsl.rb +88 -27
- data/lib/dry/schema/extensions.rb +10 -2
- data/lib/dry/schema/extensions/hints.rb +15 -8
- data/lib/dry/schema/extensions/hints/message_compiler_methods.rb +1 -1
- data/lib/dry/schema/extensions/hints/message_set_methods.rb +0 -47
- data/lib/dry/schema/extensions/info.rb +27 -0
- data/lib/dry/schema/extensions/info/schema_compiler.rb +105 -0
- data/lib/dry/schema/extensions/monads.rb +1 -1
- data/lib/dry/schema/extensions/struct.rb +32 -0
- data/lib/dry/schema/json.rb +1 -1
- data/lib/dry/schema/key.rb +16 -1
- data/lib/dry/schema/key_coercer.rb +4 -4
- data/lib/dry/schema/key_map.rb +9 -4
- data/lib/dry/schema/key_validator.rb +66 -0
- data/lib/dry/schema/macros.rb +8 -8
- data/lib/dry/schema/macros/array.rb +17 -4
- data/lib/dry/schema/macros/core.rb +9 -4
- data/lib/dry/schema/macros/dsl.rb +34 -19
- data/lib/dry/schema/macros/each.rb +4 -4
- data/lib/dry/schema/macros/filled.rb +5 -5
- data/lib/dry/schema/macros/hash.rb +21 -3
- data/lib/dry/schema/macros/key.rb +9 -9
- data/lib/dry/schema/macros/maybe.rb +3 -3
- data/lib/dry/schema/macros/optional.rb +1 -1
- data/lib/dry/schema/macros/required.rb +1 -1
- data/lib/dry/schema/macros/schema.rb +23 -2
- data/lib/dry/schema/macros/value.rb +32 -10
- data/lib/dry/schema/message.rb +35 -9
- data/lib/dry/schema/message/or.rb +18 -39
- data/lib/dry/schema/message/or/abstract.rb +28 -0
- data/lib/dry/schema/message/or/multi_path.rb +37 -0
- data/lib/dry/schema/message/or/single_path.rb +64 -0
- data/lib/dry/schema/message_compiler.rb +37 -17
- data/lib/dry/schema/message_compiler/visitor_opts.rb +2 -2
- data/lib/dry/schema/message_set.rb +25 -36
- data/lib/dry/schema/messages.rb +6 -6
- data/lib/dry/schema/messages/abstract.rb +54 -56
- data/lib/dry/schema/messages/i18n.rb +29 -27
- data/lib/dry/schema/messages/namespaced.rb +12 -2
- data/lib/dry/schema/messages/template.rb +19 -44
- data/lib/dry/schema/messages/yaml.rb +60 -13
- data/lib/dry/schema/params.rb +1 -1
- data/lib/dry/schema/path.rb +44 -5
- data/lib/dry/schema/predicate.rb +2 -2
- data/lib/dry/schema/predicate_inferrer.rb +4 -184
- data/lib/dry/schema/predicate_registry.rb +2 -2
- data/lib/dry/schema/primitive_inferrer.rb +16 -0
- data/lib/dry/schema/processor.rb +49 -28
- data/lib/dry/schema/processor_steps.rb +50 -27
- data/lib/dry/schema/result.rb +43 -5
- data/lib/dry/schema/rule_applier.rb +8 -7
- data/lib/dry/schema/step.rb +79 -0
- data/lib/dry/schema/trace.rb +5 -4
- data/lib/dry/schema/type_container.rb +3 -3
- data/lib/dry/schema/type_registry.rb +2 -2
- data/lib/dry/schema/types.rb +1 -1
- data/lib/dry/schema/value_coercer.rb +2 -2
- data/lib/dry/schema/version.rb +1 -1
- metadata +22 -8
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/initializer"
|
4
4
|
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
5
|
+
require "dry/schema/constants"
|
6
|
+
require "dry/schema/compiler"
|
7
|
+
require "dry/schema/trace"
|
8
8
|
|
9
9
|
module Dry
|
10
10
|
module Schema
|
@@ -32,6 +32,11 @@ module Dry
|
|
32
32
|
self.class.new(name: name, compiler: compiler, schema_dsl: schema_dsl, **options)
|
33
33
|
end
|
34
34
|
|
35
|
+
# @api private
|
36
|
+
def path
|
37
|
+
schema_dsl.path
|
38
|
+
end
|
39
|
+
|
35
40
|
# @api private
|
36
41
|
def to_rule
|
37
42
|
compiler.visit(to_ast)
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require 'dry/types/predicate_inferrer'
|
5
|
-
require 'dry/types/primitive_inferrer'
|
3
|
+
require "dry/logic/operators"
|
6
4
|
|
7
|
-
require
|
5
|
+
require "dry/schema/macros/core"
|
6
|
+
require "dry/schema/predicate_inferrer"
|
7
|
+
require "dry/schema/primitive_inferrer"
|
8
8
|
|
9
9
|
module Dry
|
10
10
|
module Schema
|
@@ -28,13 +28,13 @@ module Dry
|
|
28
28
|
# PredicateInferrer is used to infer predicate type-check from a type spec
|
29
29
|
# @return [PredicateInferrer]
|
30
30
|
# @api private
|
31
|
-
option :predicate_inferrer, default: proc {
|
31
|
+
option :predicate_inferrer, default: proc { PredicateInferrer.new(compiler.predicates) }
|
32
32
|
|
33
33
|
# @!attribute [r] primitive_inferrer
|
34
34
|
# PrimitiveInferrer used to get a list of primitive classes from configured type
|
35
35
|
# @return [PrimitiveInferrer]
|
36
36
|
# @api private
|
37
|
-
option :primitive_inferrer, default: proc {
|
37
|
+
option :primitive_inferrer, default: proc { PrimitiveInferrer.new }
|
38
38
|
|
39
39
|
# @overload value(*predicates, **predicate_opts)
|
40
40
|
# Set predicates without and with arguments
|
@@ -177,6 +177,11 @@ module Dry
|
|
177
177
|
self
|
178
178
|
end
|
179
179
|
|
180
|
+
# @api private
|
181
|
+
def custom_type?
|
182
|
+
schema_dsl.custom_type?(name)
|
183
|
+
end
|
184
|
+
|
180
185
|
private
|
181
186
|
|
182
187
|
# @api private
|
@@ -195,29 +200,32 @@ module Dry
|
|
195
200
|
|
196
201
|
# @api private
|
197
202
|
def extract_type_spec(*args, nullable: false, set_type: true)
|
198
|
-
type_spec = args[0]
|
199
|
-
|
200
|
-
is_type_spec = type_spec.is_a?(Dry::Schema::Processor) ||
|
201
|
-
type_spec.is_a?(Symbol) &&
|
202
|
-
type_spec.to_s.end_with?(QUESTION_MARK)
|
203
|
-
|
204
|
-
type_spec = nil if is_type_spec
|
203
|
+
type_spec = args[0] unless schema_or_predicate?(args[0])
|
205
204
|
|
206
205
|
predicates = Array(type_spec ? args[1..-1] : args)
|
206
|
+
type_rule = nil
|
207
207
|
|
208
208
|
if type_spec
|
209
209
|
resolved_type = resolve_type(type_spec, nullable)
|
210
210
|
|
211
|
-
|
212
|
-
|
213
|
-
|
211
|
+
if type_spec.is_a?(::Array)
|
212
|
+
type_rule = type_spec.map { |ts| new(chain: false).value(ts) }.reduce(:|)
|
213
|
+
else
|
214
|
+
type_predicates = predicate_inferrer[resolved_type]
|
214
215
|
|
215
|
-
|
216
|
+
predicates.replace(type_predicates + predicates) unless type_predicates.empty?
|
216
217
|
|
217
|
-
|
218
|
+
return self if predicates.empty?
|
219
|
+
end
|
218
220
|
end
|
219
221
|
|
220
|
-
|
222
|
+
type(resolved_type) if set_type && resolved_type
|
223
|
+
|
224
|
+
if type_rule
|
225
|
+
yield(*predicates, type_spec: nil, type_rule: type_rule)
|
226
|
+
else
|
227
|
+
yield(*predicates, type_spec: type_spec, type_rule: nil)
|
228
|
+
end
|
221
229
|
end
|
222
230
|
|
223
231
|
# @api private
|
@@ -230,6 +238,13 @@ module Dry
|
|
230
238
|
schema_dsl.resolve_type([:nil, resolved])
|
231
239
|
end
|
232
240
|
end
|
241
|
+
|
242
|
+
# @api private
|
243
|
+
def schema_or_predicate?(arg)
|
244
|
+
arg.is_a?(Dry::Schema::Processor) ||
|
245
|
+
arg.is_a?(Symbol) &&
|
246
|
+
arg.to_s.end_with?(QUESTION_MARK)
|
247
|
+
end
|
233
248
|
end
|
234
249
|
end
|
235
250
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/types/type"
|
4
|
+
require "dry/schema/macros/dsl"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Schema
|
@@ -12,12 +12,12 @@ module Dry
|
|
12
12
|
class Each < DSL
|
13
13
|
# @api private
|
14
14
|
def value(*args, **opts)
|
15
|
-
extract_type_spec(*args, set_type: false) do |*predicates, type_spec:|
|
15
|
+
extract_type_spec(*args, set_type: false) do |*predicates, type_spec:, type_rule:|
|
16
16
|
if type_spec && !type_spec.is_a?(Dry::Types::Type)
|
17
17
|
type(schema_dsl.array[type_spec])
|
18
18
|
end
|
19
19
|
|
20
|
-
super(*predicates, type_spec: type_spec, **opts)
|
20
|
+
super(*predicates, type_spec: type_spec, type_rule: type_rule, **opts)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/schema/macros/value"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Schema
|
@@ -15,23 +15,23 @@ module Dry
|
|
15
15
|
|
16
16
|
if opts[:type_spec] && !filter_empty_string?
|
17
17
|
value(predicates[0], :filled?, *predicates[1..predicates.size - 1], **opts, &block)
|
18
|
+
elsif opts[:type_rule]
|
19
|
+
value(:filled?).value(*predicates, **opts, &block)
|
18
20
|
else
|
19
21
|
value(:filled?, *predicates, **opts, &block)
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
# @api private
|
24
|
-
# rubocop:disable Style/GuardClause
|
25
26
|
def ensure_valid_predicates(predicates)
|
26
27
|
if predicates.include?(:empty?)
|
27
|
-
raise ::Dry::Schema::InvalidSchemaError,
|
28
|
+
raise ::Dry::Schema::InvalidSchemaError, "Using filled with empty? predicate is invalid"
|
28
29
|
end
|
29
30
|
|
30
31
|
if predicates.include?(:filled?)
|
31
|
-
raise ::Dry::Schema::InvalidSchemaError,
|
32
|
+
raise ::Dry::Schema::InvalidSchemaError, "Using filled with filled? is redundant"
|
32
33
|
end
|
33
34
|
end
|
34
|
-
# rubocop:enable Style/GuardClause
|
35
35
|
|
36
36
|
# @api private
|
37
37
|
def filter_empty_string?
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/schema/macros/schema"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Schema
|
@@ -11,8 +11,26 @@ module Dry
|
|
11
11
|
class Hash < Schema
|
12
12
|
# @api private
|
13
13
|
def call(*args, &block)
|
14
|
-
|
15
|
-
|
14
|
+
if args.size >= 1 && args[0].respond_to?(:keys)
|
15
|
+
hash_type = args[0]
|
16
|
+
type_predicates = predicate_inferrer[hash_type]
|
17
|
+
all_predicats = type_predicates + args.drop(1)
|
18
|
+
|
19
|
+
super(*all_predicats) do
|
20
|
+
hash_type.each do |key|
|
21
|
+
if key.required?
|
22
|
+
required(key.name).value(key.type)
|
23
|
+
else
|
24
|
+
optional(key.name).value(key.type)
|
25
|
+
end
|
26
|
+
instance_exec(&block) if block
|
27
|
+
end
|
28
|
+
end
|
29
|
+
else
|
30
|
+
trace << hash?
|
31
|
+
|
32
|
+
super(*args, &block)
|
33
|
+
end
|
16
34
|
end
|
17
35
|
end
|
18
36
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "dry/schema/processor"
|
4
|
+
require "dry/schema/macros/dsl"
|
5
|
+
require "dry/schema/constants"
|
6
6
|
|
7
7
|
module Dry
|
8
8
|
module Schema
|
@@ -54,8 +54,8 @@ module Dry
|
|
54
54
|
#
|
55
55
|
# @api public
|
56
56
|
def value(*args, **opts, &block)
|
57
|
-
extract_type_spec(*args) do |*predicates, type_spec:|
|
58
|
-
super(*predicates, type_spec: type_spec, **opts, &block)
|
57
|
+
extract_type_spec(*args) do |*predicates, type_spec:, type_rule:|
|
58
|
+
super(*predicates, type_spec: type_spec, type_rule: type_rule, **opts, &block)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -70,8 +70,8 @@ module Dry
|
|
70
70
|
#
|
71
71
|
# @api public
|
72
72
|
def filled(*args, **opts, &block)
|
73
|
-
extract_type_spec(*args) do |*predicates, type_spec:|
|
74
|
-
super(*predicates, type_spec: type_spec, **opts, &block)
|
73
|
+
extract_type_spec(*args) do |*predicates, type_spec:, type_rule:|
|
74
|
+
super(*predicates, type_spec: type_spec, type_rule: type_rule, **opts, &block)
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -86,9 +86,9 @@ module Dry
|
|
86
86
|
#
|
87
87
|
# @api public
|
88
88
|
def maybe(*args, **opts, &block)
|
89
|
-
extract_type_spec(*args, nullable: true) do |*predicates, type_spec:|
|
89
|
+
extract_type_spec(*args, nullable: true) do |*predicates, type_spec:, type_rule:|
|
90
90
|
append_macro(Macros::Maybe) do |macro|
|
91
|
-
macro.call(*predicates, type_spec: type_spec, **opts, &block)
|
91
|
+
macro.call(*predicates, type_spec: type_spec, type_rule: type_rule, **opts, &block)
|
92
92
|
end
|
93
93
|
end
|
94
94
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/schema/macros/dsl"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Schema
|
@@ -12,11 +12,11 @@ module Dry
|
|
12
12
|
# @api private
|
13
13
|
def call(*args, **opts, &block)
|
14
14
|
if args.include?(:empty?)
|
15
|
-
raise ::Dry::Schema::InvalidSchemaError,
|
15
|
+
raise ::Dry::Schema::InvalidSchemaError, "Using maybe with empty? predicate is invalid"
|
16
16
|
end
|
17
17
|
|
18
18
|
if args.include?(:nil?)
|
19
|
-
raise ::Dry::Schema::InvalidSchemaError,
|
19
|
+
raise ::Dry::Schema::InvalidSchemaError, "Using maybe with nil? predicate is redundant"
|
20
20
|
end
|
21
21
|
|
22
22
|
value(*args, **opts, &block)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/schema/macros/value"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Schema
|
@@ -13,8 +13,13 @@ module Dry
|
|
13
13
|
def call(*args, &block)
|
14
14
|
super(*args, &nil) unless args.empty?
|
15
15
|
|
16
|
+
if args.size.equal?(1) && (op = args.first).is_a?(Dry::Logic::Operations::Abstract)
|
17
|
+
process_operation(op)
|
18
|
+
end
|
19
|
+
|
16
20
|
if block
|
17
21
|
schema = define(*args, &block)
|
22
|
+
import_steps(schema)
|
18
23
|
trace << schema.to_rule
|
19
24
|
end
|
20
25
|
|
@@ -23,9 +28,25 @@ module Dry
|
|
23
28
|
|
24
29
|
private
|
25
30
|
|
31
|
+
# @api private
|
32
|
+
def process_operation(op)
|
33
|
+
schemas = op.rules.select { |rule| rule.is_a?(Processor) }
|
34
|
+
|
35
|
+
hash_schema = hash_type.schema(
|
36
|
+
schemas.map(&:schema_dsl).map(&:types).reduce(:merge)
|
37
|
+
)
|
38
|
+
|
39
|
+
type(hash_schema)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @api private
|
43
|
+
def hash_type
|
44
|
+
schema_dsl.resolve_type(:hash)
|
45
|
+
end
|
46
|
+
|
26
47
|
# @api private
|
27
48
|
def define(*args, &block)
|
28
|
-
definition = schema_dsl.new(&block)
|
49
|
+
definition = schema_dsl.new(path: schema_dsl.path, &block)
|
29
50
|
schema = definition.call
|
30
51
|
type_schema =
|
31
52
|
if array_type?(parent_type)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/schema/path"
|
4
|
+
require "dry/schema/macros/dsl"
|
4
5
|
|
5
6
|
module Dry
|
6
7
|
module Schema
|
@@ -13,6 +14,8 @@ module Dry
|
|
13
14
|
def call(*predicates, **opts, &block)
|
14
15
|
schema = predicates.detect { |predicate| predicate.is_a?(Processor) }
|
15
16
|
|
17
|
+
type_spec = opts[:type_spec]
|
18
|
+
|
16
19
|
if schema
|
17
20
|
current_type = schema_dsl.types[name]
|
18
21
|
|
@@ -23,20 +26,30 @@ module Dry
|
|
23
26
|
schema.type_schema
|
24
27
|
end
|
25
28
|
|
26
|
-
|
29
|
+
import_steps(schema)
|
30
|
+
|
31
|
+
type(updated_type) unless custom_type? && !current_type.respond_to?(:of)
|
27
32
|
end
|
28
33
|
|
29
|
-
|
34
|
+
trace_opts = opts.reject { |key, _| key == :type_spec || key == :type_rule }
|
30
35
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
trace.
|
36
|
+
if (type_rule = opts[:type_rule])
|
37
|
+
trace.append(type_rule).evaluate(*predicates, **trace_opts)
|
38
|
+
trace.append(new(chain: false).instance_exec(&block)) if block
|
39
|
+
else
|
40
|
+
trace.evaluate(*predicates, **trace_opts)
|
41
|
+
|
42
|
+
if block && type_spec.equal?(:hash)
|
43
|
+
hash(&block)
|
44
|
+
elsif type_spec.is_a?(::Dry::Types::Type) && hash_type?(type_spec)
|
45
|
+
hash(type_spec)
|
46
|
+
elsif block
|
47
|
+
trace.append(new(chain: false).instance_exec(&block))
|
48
|
+
end
|
36
49
|
end
|
37
50
|
|
38
51
|
if trace.captures.empty?
|
39
|
-
raise ArgumentError,
|
52
|
+
raise ArgumentError, "wrong number of arguments (given 0, expected at least 1)"
|
40
53
|
end
|
41
54
|
|
42
55
|
each(type_spec.type.member) if type_spec.respond_to?(:member)
|
@@ -49,12 +62,16 @@ module Dry
|
|
49
62
|
primitive_inferrer[type].eql?([::Array])
|
50
63
|
end
|
51
64
|
|
65
|
+
def hash_type?(type)
|
66
|
+
primitive_inferrer[type].eql?([::Hash])
|
67
|
+
end
|
68
|
+
|
52
69
|
# @api private
|
53
70
|
def build_array_type(array_type, member)
|
54
71
|
if array_type.respond_to?(:of)
|
55
72
|
array_type.of(member)
|
56
73
|
else
|
57
|
-
raise ArgumentError, <<~ERROR.split("\n").join(
|
74
|
+
raise ArgumentError, <<~ERROR.split("\n").join(" ")
|
58
75
|
Cannot define schema for a nominal array type.
|
59
76
|
Array types must be instances of Dry::Types::Array,
|
60
77
|
usually constructed with Types::Constructor(Array) { ... } or
|
@@ -63,6 +80,11 @@ module Dry
|
|
63
80
|
end
|
64
81
|
end
|
65
82
|
|
83
|
+
# @api private
|
84
|
+
def import_steps(schema)
|
85
|
+
schema_dsl.steps.import_callbacks(Path[[*path, name]], schema.steps)
|
86
|
+
end
|
87
|
+
|
66
88
|
# @api private
|
67
89
|
def respond_to_missing?(meth, include_private = false)
|
68
90
|
super || meth.to_s.end_with?(QUESTION_MARK)
|
data/lib/dry/schema/message.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/initializer"
|
4
|
+
require "dry/equalizer"
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
6
|
+
require "dry/schema/path"
|
7
|
+
require "dry/schema/message/or"
|
8
8
|
|
9
9
|
module Dry
|
10
10
|
module Schema
|
@@ -52,9 +52,22 @@ module Dry
|
|
52
52
|
#
|
53
53
|
# @api public
|
54
54
|
def dump
|
55
|
-
@dump ||= meta.empty? ? text : {
|
55
|
+
@dump ||= meta.empty? ? text : {text: text, **meta}
|
56
|
+
end
|
57
|
+
alias_method :to_s, :dump
|
58
|
+
|
59
|
+
# Dump the message into a hash
|
60
|
+
#
|
61
|
+
# The hash will be deeply nested if the path's size is greater than 1
|
62
|
+
#
|
63
|
+
# @see Message#to_h
|
64
|
+
#
|
65
|
+
# @return [Hash]
|
66
|
+
#
|
67
|
+
# @api public
|
68
|
+
def to_h
|
69
|
+
@to_h ||= _path.to_h(dump)
|
56
70
|
end
|
57
|
-
alias to_s dump
|
58
71
|
|
59
72
|
# See if another message is the same
|
60
73
|
#
|
@@ -69,19 +82,32 @@ module Dry
|
|
69
82
|
other.is_a?(String) ? text == other : super
|
70
83
|
end
|
71
84
|
|
85
|
+
# @api private
|
86
|
+
def to_or(root)
|
87
|
+
clone = dup
|
88
|
+
clone.instance_variable_set("@path", path - root.to_a)
|
89
|
+
clone.instance_variable_set("@_path", nil)
|
90
|
+
clone
|
91
|
+
end
|
92
|
+
|
72
93
|
# See which message is higher in the hierarchy
|
73
94
|
#
|
74
95
|
# @api private
|
75
96
|
def <=>(other)
|
76
|
-
l_path =
|
77
|
-
r_path =
|
97
|
+
l_path = _path
|
98
|
+
r_path = other._path
|
78
99
|
|
79
100
|
unless l_path.same_root?(r_path)
|
80
|
-
raise ArgumentError,
|
101
|
+
raise ArgumentError, "Cannot compare messages from different root paths"
|
81
102
|
end
|
82
103
|
|
83
104
|
l_path <=> r_path
|
84
105
|
end
|
106
|
+
|
107
|
+
# @api private
|
108
|
+
def _path
|
109
|
+
@_path ||= Path[path]
|
110
|
+
end
|
85
111
|
end
|
86
112
|
end
|
87
113
|
end
|