mega-sharp-sys 0.0.1
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 +7 -0
- data/dry-schema-1.16.0/CHANGELOG.md +901 -0
- data/dry-schema-1.16.0/LICENSE +20 -0
- data/dry-schema-1.16.0/README.md +17 -0
- data/dry-schema-1.16.0/config/errors.yml +127 -0
- data/dry-schema-1.16.0/dry-schema.gemspec +50 -0
- data/dry-schema-1.16.0/lib/dry/schema/compiler.rb +51 -0
- data/dry-schema-1.16.0/lib/dry/schema/config.rb +83 -0
- data/dry-schema-1.16.0/lib/dry/schema/constants.rb +47 -0
- data/dry-schema-1.16.0/lib/dry/schema/dsl.rb +517 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions/hints/compiler_methods.rb +19 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions/hints/message_compiler_methods.rb +89 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions/hints/message_set_methods.rb +44 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions/hints/result_methods.rb +47 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions/hints.rb +65 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions/info/schema_compiler.rb +123 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions/info.rb +27 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions/json_schema/schema_compiler.rb +314 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions/json_schema.rb +29 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions/monads.rb +32 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions/struct.rb +62 -0
- data/dry-schema-1.16.0/lib/dry/schema/extensions.rb +21 -0
- data/dry-schema-1.16.0/lib/dry/schema/json.rb +17 -0
- data/dry-schema-1.16.0/lib/dry/schema/key.rb +184 -0
- data/dry-schema-1.16.0/lib/dry/schema/key_coercer.rb +41 -0
- data/dry-schema-1.16.0/lib/dry/schema/key_map.rb +136 -0
- data/dry-schema-1.16.0/lib/dry/schema/key_validator.rb +117 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/array.rb +54 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/core.rb +55 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/dsl.rb +282 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/each.rb +31 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/filled.rb +58 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/hash.rb +36 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/key.rb +50 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/maybe.rb +38 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/optional.rb +22 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/required.rb +17 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/schema.rb +103 -0
- data/dry-schema-1.16.0/lib/dry/schema/macros/value.rb +125 -0
- data/dry-schema-1.16.0/lib/dry/schema/message/or/abstract.rb +28 -0
- data/dry-schema-1.16.0/lib/dry/schema/message/or/multi_path.rb +100 -0
- data/dry-schema-1.16.0/lib/dry/schema/message/or/single_path.rb +72 -0
- data/dry-schema-1.16.0/lib/dry/schema/message/or.rb +30 -0
- data/dry-schema-1.16.0/lib/dry/schema/message.rb +116 -0
- data/dry-schema-1.16.0/lib/dry/schema/message_compiler/visitor_opts.rb +56 -0
- data/dry-schema-1.16.0/lib/dry/schema/message_compiler.rb +234 -0
- data/dry-schema-1.16.0/lib/dry/schema/message_set.rb +144 -0
- data/dry-schema-1.16.0/lib/dry/schema/messages/abstract.rb +202 -0
- data/dry-schema-1.16.0/lib/dry/schema/messages/i18n.rb +139 -0
- data/dry-schema-1.16.0/lib/dry/schema/messages/namespaced.rb +93 -0
- data/dry-schema-1.16.0/lib/dry/schema/messages/template.rb +43 -0
- data/dry-schema-1.16.0/lib/dry/schema/messages/yaml.rb +209 -0
- data/dry-schema-1.16.0/lib/dry/schema/messages.rb +32 -0
- data/dry-schema-1.16.0/lib/dry/schema/namespaced_rule.rb +38 -0
- data/dry-schema-1.16.0/lib/dry/schema/params.rb +17 -0
- data/dry-schema-1.16.0/lib/dry/schema/path.rb +107 -0
- data/dry-schema-1.16.0/lib/dry/schema/predicate.rb +102 -0
- data/dry-schema-1.16.0/lib/dry/schema/predicate_inferrer.rb +25 -0
- data/dry-schema-1.16.0/lib/dry/schema/predicate_registry.rb +22 -0
- data/dry-schema-1.16.0/lib/dry/schema/primitive_inferrer.rb +22 -0
- data/dry-schema-1.16.0/lib/dry/schema/processor.rb +213 -0
- data/dry-schema-1.16.0/lib/dry/schema/processor_steps.rb +141 -0
- data/dry-schema-1.16.0/lib/dry/schema/result.rb +203 -0
- data/dry-schema-1.16.0/lib/dry/schema/rule_applier.rb +47 -0
- data/dry-schema-1.16.0/lib/dry/schema/step.rb +59 -0
- data/dry-schema-1.16.0/lib/dry/schema/trace.rb +114 -0
- data/dry-schema-1.16.0/lib/dry/schema/type_container.rb +27 -0
- data/dry-schema-1.16.0/lib/dry/schema/type_registry.rb +44 -0
- data/dry-schema-1.16.0/lib/dry/schema/types.rb +14 -0
- data/dry-schema-1.16.0/lib/dry/schema/types_merger.rb +139 -0
- data/dry-schema-1.16.0/lib/dry/schema/value_coercer.rb +36 -0
- data/dry-schema-1.16.0/lib/dry/schema/version.rb +7 -0
- data/dry-schema-1.16.0/lib/dry/schema.rb +114 -0
- data/dry-schema-1.16.0/lib/dry-schema.rb +3 -0
- data/mega-sharp-sys.gemspec +11 -0
- metadata +114 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module Schema
|
|
5
|
+
module Macros
|
|
6
|
+
# A macro used for specifying predicates to be applied to values from a hash
|
|
7
|
+
#
|
|
8
|
+
# @api private
|
|
9
|
+
class Value < DSL
|
|
10
|
+
# @api private
|
|
11
|
+
#
|
|
12
|
+
# rubocop:disable Metrics/AbcSize
|
|
13
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
14
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
15
|
+
def call(*args, **opts, &)
|
|
16
|
+
types, predicates = args.partition { _1.is_a?(::Dry::Types::Type) }
|
|
17
|
+
|
|
18
|
+
constructor = types.select { _1.is_a?(::Dry::Types::Constructor) }.reduce(:>>)
|
|
19
|
+
schema = predicates.detect { _1.is_a?(Processor) }
|
|
20
|
+
|
|
21
|
+
schema_dsl.set_type(name, constructor) if constructor
|
|
22
|
+
|
|
23
|
+
type_spec = opts[:type_spec]
|
|
24
|
+
|
|
25
|
+
if schema
|
|
26
|
+
current_type = schema_dsl.types[name]
|
|
27
|
+
|
|
28
|
+
updated_type =
|
|
29
|
+
if array_type?(current_type)
|
|
30
|
+
build_array_type(current_type, schema.strict_type_schema)
|
|
31
|
+
else
|
|
32
|
+
schema.strict_type_schema
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
import_steps(schema)
|
|
36
|
+
|
|
37
|
+
if !custom_type? || array_type?(current_type) || hash_type?(current_type)
|
|
38
|
+
type(updated_type)
|
|
39
|
+
elsif maybe_type?(current_type)
|
|
40
|
+
type(updated_type.optional)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
trace_opts = opts.except(:type_spec, :type_rule)
|
|
45
|
+
|
|
46
|
+
if (type_rule = opts[:type_rule])
|
|
47
|
+
trace.append(type_rule).evaluate(*predicates, **trace_opts)
|
|
48
|
+
trace.append(new(chain: false).instance_exec(&)) if block_given?
|
|
49
|
+
else
|
|
50
|
+
trace.evaluate(*predicates, **trace_opts)
|
|
51
|
+
|
|
52
|
+
if block_given? && type_spec.equal?(:hash)
|
|
53
|
+
hash(&)
|
|
54
|
+
elsif type_spec.is_a?(::Dry::Types::Type) && hash_type?(type_spec)
|
|
55
|
+
hash(type_spec)
|
|
56
|
+
elsif block_given?
|
|
57
|
+
trace.append(new(chain: false).instance_exec(&))
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if trace.captures.empty?
|
|
62
|
+
raise ArgumentError, "wrong number of arguments (given 0, expected at least 1)"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
each(type_spec.type.member) if type_spec.respond_to?(:member)
|
|
66
|
+
|
|
67
|
+
self
|
|
68
|
+
end
|
|
69
|
+
# rubocop:enable Metrics/AbcSize
|
|
70
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
71
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
72
|
+
|
|
73
|
+
# @api private
|
|
74
|
+
def array_type?(type)
|
|
75
|
+
primitive_inferrer[type].eql?([::Array])
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @api private
|
|
79
|
+
def hash_type?(type)
|
|
80
|
+
primitive_inferrer[type].eql?([::Hash])
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# @api private
|
|
84
|
+
def maybe_type?(type)
|
|
85
|
+
type.meta[:maybe].equal?(true)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @api private
|
|
89
|
+
def build_array_type(array_type, member)
|
|
90
|
+
if array_type.respond_to?(:of)
|
|
91
|
+
array_type.of(member)
|
|
92
|
+
else
|
|
93
|
+
raise ArgumentError, <<~ERROR.split("\n").join(" ")
|
|
94
|
+
Cannot define schema for a nominal array type.
|
|
95
|
+
Array types must be instances of Dry::Types::Array,
|
|
96
|
+
usually constructed with Types::Constructor(Array) { ... } or
|
|
97
|
+
Dry::Types['array'].constructor { ... }
|
|
98
|
+
ERROR
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# @api private
|
|
103
|
+
def import_steps(schema)
|
|
104
|
+
schema_dsl.steps.import_callbacks(Path[[*path, name]], schema.steps)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# @api private
|
|
108
|
+
def respond_to_missing?(meth, include_private = false)
|
|
109
|
+
super || meth.to_s.end_with?(QUESTION_MARK)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
private
|
|
113
|
+
|
|
114
|
+
# @api private
|
|
115
|
+
def method_missing(meth, ...)
|
|
116
|
+
if meth.to_s.end_with?(QUESTION_MARK)
|
|
117
|
+
trace.__send__(meth, ...)
|
|
118
|
+
else
|
|
119
|
+
super
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module Schema
|
|
5
|
+
class Message
|
|
6
|
+
module Or
|
|
7
|
+
# A message type used by OR operations
|
|
8
|
+
#
|
|
9
|
+
# @abstract
|
|
10
|
+
#
|
|
11
|
+
# @api private
|
|
12
|
+
class Abstract
|
|
13
|
+
# @api private
|
|
14
|
+
attr_reader :left
|
|
15
|
+
|
|
16
|
+
# @api private
|
|
17
|
+
attr_reader :right
|
|
18
|
+
|
|
19
|
+
# @api private
|
|
20
|
+
def initialize(left, right)
|
|
21
|
+
@left = left
|
|
22
|
+
@right = right
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module Schema
|
|
5
|
+
class Message
|
|
6
|
+
module Or
|
|
7
|
+
# A message type used by OR operations with different paths
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
class MultiPath < Abstract
|
|
11
|
+
# @api private
|
|
12
|
+
class MessageArray
|
|
13
|
+
# @api private
|
|
14
|
+
def initialize(messages)
|
|
15
|
+
@messages = messages.flatten
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @api private
|
|
19
|
+
def _paths
|
|
20
|
+
@messages.map(&:_path)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @api private
|
|
24
|
+
def to_or(root)
|
|
25
|
+
self.class.new(@messages.map { _1.to_or(root) })
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @api private
|
|
29
|
+
def to_h
|
|
30
|
+
MessageSet.new(@messages).to_h
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
MESSAGE_ARRAY_HANDLER = -> { MessageArray.new(_1) }
|
|
35
|
+
|
|
36
|
+
# @api private
|
|
37
|
+
def self.handler(message)
|
|
38
|
+
case message
|
|
39
|
+
when self
|
|
40
|
+
IDENTITY
|
|
41
|
+
when Array
|
|
42
|
+
MESSAGE_ARRAY_HANDLER
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @api public
|
|
47
|
+
def to_h
|
|
48
|
+
@to_h ||= Path[[*root, :or]].to_h(messages.map(&:to_h))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @api private
|
|
52
|
+
def messages
|
|
53
|
+
@messages ||= _messages.flat_map { _1.to_or(root) }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @api private
|
|
57
|
+
def root
|
|
58
|
+
@root ||= _paths.reduce(:&)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @api private
|
|
62
|
+
def path
|
|
63
|
+
root
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @api private
|
|
67
|
+
def _path
|
|
68
|
+
@_path ||= Path[root]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @api private
|
|
72
|
+
def _paths
|
|
73
|
+
@paths ||= _messages.flat_map(&:_paths)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# @api private
|
|
77
|
+
def to_or(root)
|
|
78
|
+
self.root == root ? messages : [self]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# @api private
|
|
84
|
+
def _messages
|
|
85
|
+
@_messages ||= [left, right].map do |message|
|
|
86
|
+
handler = self.class.handler(message)
|
|
87
|
+
|
|
88
|
+
unless handler
|
|
89
|
+
raise ArgumentError,
|
|
90
|
+
"#{message.inspect} is of unknown type #{message.class.inspect}"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
handler.(message)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module Schema
|
|
5
|
+
class Message
|
|
6
|
+
module Or
|
|
7
|
+
# A message type used by OR operations with the same path
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
class SinglePath < Abstract
|
|
11
|
+
# @api private
|
|
12
|
+
attr_reader :path
|
|
13
|
+
|
|
14
|
+
# @api private
|
|
15
|
+
attr_reader :_path
|
|
16
|
+
|
|
17
|
+
# @api private
|
|
18
|
+
attr_reader :messages
|
|
19
|
+
|
|
20
|
+
# @api private
|
|
21
|
+
def initialize(*args, messages)
|
|
22
|
+
super(*args.map { [_1].flatten })
|
|
23
|
+
@messages = messages
|
|
24
|
+
message = left.first
|
|
25
|
+
@path = message.path
|
|
26
|
+
@_path = message._path
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Dump a message into a string
|
|
30
|
+
#
|
|
31
|
+
# Both sides of the message will be joined using translated
|
|
32
|
+
# value under `dry_schema.or` message key
|
|
33
|
+
#
|
|
34
|
+
# @see Message#dump
|
|
35
|
+
#
|
|
36
|
+
# @return [String]
|
|
37
|
+
#
|
|
38
|
+
# @api public
|
|
39
|
+
def dump
|
|
40
|
+
@dump ||= [*left, *right].map(&:dump).join(" #{messages[:or]} ")
|
|
41
|
+
end
|
|
42
|
+
alias_method :to_s, :dump
|
|
43
|
+
|
|
44
|
+
# Dump an `or` message into a hash
|
|
45
|
+
#
|
|
46
|
+
# @see Message#to_h
|
|
47
|
+
#
|
|
48
|
+
# @return [String]
|
|
49
|
+
#
|
|
50
|
+
# @api public
|
|
51
|
+
def to_h
|
|
52
|
+
@to_h ||= _path.to_h(dump)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @api private
|
|
56
|
+
def to_a
|
|
57
|
+
@to_a ||= [*left, *right]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# @api private
|
|
61
|
+
def to_or(root)
|
|
62
|
+
to_ored = [left, right].map do |msgs|
|
|
63
|
+
msgs.map { _1.to_or(root) }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
self.class.new(*to_ored, messages)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module Schema
|
|
5
|
+
# Message objects used by message sets
|
|
6
|
+
#
|
|
7
|
+
# @api public
|
|
8
|
+
class Message
|
|
9
|
+
module Or
|
|
10
|
+
# @api private
|
|
11
|
+
def self.[](left, right, messages)
|
|
12
|
+
msgs = [left, right].flatten
|
|
13
|
+
paths = msgs.map(&:path)
|
|
14
|
+
|
|
15
|
+
if paths.uniq.size == 1
|
|
16
|
+
SinglePath.new(left, right, messages)
|
|
17
|
+
elsif MultiPath.handler(right)
|
|
18
|
+
if MultiPath.handler(left) && paths.uniq.size > 1
|
|
19
|
+
MultiPath.new(left, right)
|
|
20
|
+
else
|
|
21
|
+
right
|
|
22
|
+
end
|
|
23
|
+
else
|
|
24
|
+
msgs.max
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/initializer"
|
|
4
|
+
|
|
5
|
+
module Dry
|
|
6
|
+
module Schema
|
|
7
|
+
# Message objects used by message sets
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
class Message
|
|
11
|
+
include ::Dry::Equalizer(:text, :path, :predicate, :input)
|
|
12
|
+
|
|
13
|
+
extend ::Dry::Initializer
|
|
14
|
+
|
|
15
|
+
# @!attribute [r] text
|
|
16
|
+
# Message text representation created from a localized template
|
|
17
|
+
# @return [String]
|
|
18
|
+
option :text
|
|
19
|
+
|
|
20
|
+
# @!attribute [r] path
|
|
21
|
+
# Path to the value
|
|
22
|
+
# @return [String]
|
|
23
|
+
option :path
|
|
24
|
+
|
|
25
|
+
# @!attribute [r] predicate
|
|
26
|
+
# Predicate identifier that was used to produce a message
|
|
27
|
+
# @return [Symbol]
|
|
28
|
+
option :predicate
|
|
29
|
+
|
|
30
|
+
# @!attribute [r] args
|
|
31
|
+
# Optional list of arguments used by the predicate
|
|
32
|
+
# @return [Array]
|
|
33
|
+
option :args, default: proc { EMPTY_ARRAY }
|
|
34
|
+
|
|
35
|
+
# @!attribute [r] input
|
|
36
|
+
# The input value
|
|
37
|
+
# @return [Object]
|
|
38
|
+
option :input
|
|
39
|
+
|
|
40
|
+
# @!attribute [r] meta
|
|
41
|
+
# Arbitrary meta data
|
|
42
|
+
# @return [Hash]
|
|
43
|
+
option :meta, optional: true, default: proc { EMPTY_HASH }
|
|
44
|
+
|
|
45
|
+
# Dump the message to a representation suitable for the message set hash
|
|
46
|
+
#
|
|
47
|
+
# @return [String,Hash]
|
|
48
|
+
#
|
|
49
|
+
# @api public
|
|
50
|
+
def dump
|
|
51
|
+
@dump ||= meta.empty? ? text : {text: text, **meta}
|
|
52
|
+
end
|
|
53
|
+
alias_method :to_s, :dump
|
|
54
|
+
|
|
55
|
+
# Dump the message into a hash
|
|
56
|
+
#
|
|
57
|
+
# The hash will be deeply nested if the path's size is greater than 1
|
|
58
|
+
#
|
|
59
|
+
# @see Message#to_h
|
|
60
|
+
#
|
|
61
|
+
# @return [Hash]
|
|
62
|
+
#
|
|
63
|
+
# @api public
|
|
64
|
+
def to_h
|
|
65
|
+
@to_h ||= _path.to_h(dump)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# See if another message is the same
|
|
69
|
+
#
|
|
70
|
+
# If a string is passed, it will be compared with the text
|
|
71
|
+
#
|
|
72
|
+
# @param other [Message,String]
|
|
73
|
+
#
|
|
74
|
+
# @return [Boolean]
|
|
75
|
+
#
|
|
76
|
+
# @api private
|
|
77
|
+
def eql?(other)
|
|
78
|
+
other.is_a?(::String) ? text == other : super
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @api private
|
|
82
|
+
def to_or(root)
|
|
83
|
+
clone = dup
|
|
84
|
+
clone.instance_variable_set("@path", remove_prefix(path, prefix: root.to_a))
|
|
85
|
+
clone.instance_variable_set("@_path", nil)
|
|
86
|
+
clone
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# See which message is higher in the hierarchy
|
|
90
|
+
#
|
|
91
|
+
# @api private
|
|
92
|
+
def <=>(other)
|
|
93
|
+
l_path = _path
|
|
94
|
+
r_path = other._path
|
|
95
|
+
|
|
96
|
+
unless l_path.same_root?(r_path)
|
|
97
|
+
raise ::ArgumentError, "Cannot compare messages from different root paths"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
l_path <=> r_path
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# @api private
|
|
104
|
+
def _path
|
|
105
|
+
@_path ||= Path[path]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
def remove_prefix(array, prefix:)
|
|
111
|
+
has_prefix = array[0, prefix.length] == prefix
|
|
112
|
+
has_prefix ? array[prefix.length..] : array.dup
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/schema/constants"
|
|
4
|
+
|
|
5
|
+
module Dry
|
|
6
|
+
module Schema
|
|
7
|
+
# @api private
|
|
8
|
+
class MessageCompiler
|
|
9
|
+
# Optimized option hash used by visitor methods in message compiler
|
|
10
|
+
#
|
|
11
|
+
# @api private
|
|
12
|
+
class VisitorOpts < Hash
|
|
13
|
+
# @api private
|
|
14
|
+
def self.new
|
|
15
|
+
opts = super
|
|
16
|
+
opts[:path] = EMPTY_ARRAY
|
|
17
|
+
opts[:message_type] = :failure
|
|
18
|
+
opts[:current_messages] = EMPTY_ARRAY.dup
|
|
19
|
+
opts
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @api private
|
|
23
|
+
def path
|
|
24
|
+
self[:path]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @api private
|
|
28
|
+
def call(other)
|
|
29
|
+
merge(other.update(path: [*path, *other[:path]]))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def dup(current_messages = EMPTY_ARRAY.dup)
|
|
33
|
+
opts = super()
|
|
34
|
+
opts[:current_messages] = current_messages
|
|
35
|
+
opts
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def key_failure?(path)
|
|
39
|
+
failures.any? { |f| f.path == path && f.predicate.equal?(:key?) }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def failures
|
|
43
|
+
current_messages.reject(&:hint?)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def hints
|
|
47
|
+
current_messages.select(&:hint?)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def current_messages
|
|
51
|
+
self[:current_messages]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|