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.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/dry-schema-1.16.0/CHANGELOG.md +901 -0
  3. data/dry-schema-1.16.0/LICENSE +20 -0
  4. data/dry-schema-1.16.0/README.md +17 -0
  5. data/dry-schema-1.16.0/config/errors.yml +127 -0
  6. data/dry-schema-1.16.0/dry-schema.gemspec +50 -0
  7. data/dry-schema-1.16.0/lib/dry/schema/compiler.rb +51 -0
  8. data/dry-schema-1.16.0/lib/dry/schema/config.rb +83 -0
  9. data/dry-schema-1.16.0/lib/dry/schema/constants.rb +47 -0
  10. data/dry-schema-1.16.0/lib/dry/schema/dsl.rb +517 -0
  11. data/dry-schema-1.16.0/lib/dry/schema/extensions/hints/compiler_methods.rb +19 -0
  12. data/dry-schema-1.16.0/lib/dry/schema/extensions/hints/message_compiler_methods.rb +89 -0
  13. data/dry-schema-1.16.0/lib/dry/schema/extensions/hints/message_set_methods.rb +44 -0
  14. data/dry-schema-1.16.0/lib/dry/schema/extensions/hints/result_methods.rb +47 -0
  15. data/dry-schema-1.16.0/lib/dry/schema/extensions/hints.rb +65 -0
  16. data/dry-schema-1.16.0/lib/dry/schema/extensions/info/schema_compiler.rb +123 -0
  17. data/dry-schema-1.16.0/lib/dry/schema/extensions/info.rb +27 -0
  18. data/dry-schema-1.16.0/lib/dry/schema/extensions/json_schema/schema_compiler.rb +314 -0
  19. data/dry-schema-1.16.0/lib/dry/schema/extensions/json_schema.rb +29 -0
  20. data/dry-schema-1.16.0/lib/dry/schema/extensions/monads.rb +32 -0
  21. data/dry-schema-1.16.0/lib/dry/schema/extensions/struct.rb +62 -0
  22. data/dry-schema-1.16.0/lib/dry/schema/extensions.rb +21 -0
  23. data/dry-schema-1.16.0/lib/dry/schema/json.rb +17 -0
  24. data/dry-schema-1.16.0/lib/dry/schema/key.rb +184 -0
  25. data/dry-schema-1.16.0/lib/dry/schema/key_coercer.rb +41 -0
  26. data/dry-schema-1.16.0/lib/dry/schema/key_map.rb +136 -0
  27. data/dry-schema-1.16.0/lib/dry/schema/key_validator.rb +117 -0
  28. data/dry-schema-1.16.0/lib/dry/schema/macros/array.rb +54 -0
  29. data/dry-schema-1.16.0/lib/dry/schema/macros/core.rb +55 -0
  30. data/dry-schema-1.16.0/lib/dry/schema/macros/dsl.rb +282 -0
  31. data/dry-schema-1.16.0/lib/dry/schema/macros/each.rb +31 -0
  32. data/dry-schema-1.16.0/lib/dry/schema/macros/filled.rb +58 -0
  33. data/dry-schema-1.16.0/lib/dry/schema/macros/hash.rb +36 -0
  34. data/dry-schema-1.16.0/lib/dry/schema/macros/key.rb +50 -0
  35. data/dry-schema-1.16.0/lib/dry/schema/macros/maybe.rb +38 -0
  36. data/dry-schema-1.16.0/lib/dry/schema/macros/optional.rb +22 -0
  37. data/dry-schema-1.16.0/lib/dry/schema/macros/required.rb +17 -0
  38. data/dry-schema-1.16.0/lib/dry/schema/macros/schema.rb +103 -0
  39. data/dry-schema-1.16.0/lib/dry/schema/macros/value.rb +125 -0
  40. data/dry-schema-1.16.0/lib/dry/schema/message/or/abstract.rb +28 -0
  41. data/dry-schema-1.16.0/lib/dry/schema/message/or/multi_path.rb +100 -0
  42. data/dry-schema-1.16.0/lib/dry/schema/message/or/single_path.rb +72 -0
  43. data/dry-schema-1.16.0/lib/dry/schema/message/or.rb +30 -0
  44. data/dry-schema-1.16.0/lib/dry/schema/message.rb +116 -0
  45. data/dry-schema-1.16.0/lib/dry/schema/message_compiler/visitor_opts.rb +56 -0
  46. data/dry-schema-1.16.0/lib/dry/schema/message_compiler.rb +234 -0
  47. data/dry-schema-1.16.0/lib/dry/schema/message_set.rb +144 -0
  48. data/dry-schema-1.16.0/lib/dry/schema/messages/abstract.rb +202 -0
  49. data/dry-schema-1.16.0/lib/dry/schema/messages/i18n.rb +139 -0
  50. data/dry-schema-1.16.0/lib/dry/schema/messages/namespaced.rb +93 -0
  51. data/dry-schema-1.16.0/lib/dry/schema/messages/template.rb +43 -0
  52. data/dry-schema-1.16.0/lib/dry/schema/messages/yaml.rb +209 -0
  53. data/dry-schema-1.16.0/lib/dry/schema/messages.rb +32 -0
  54. data/dry-schema-1.16.0/lib/dry/schema/namespaced_rule.rb +38 -0
  55. data/dry-schema-1.16.0/lib/dry/schema/params.rb +17 -0
  56. data/dry-schema-1.16.0/lib/dry/schema/path.rb +107 -0
  57. data/dry-schema-1.16.0/lib/dry/schema/predicate.rb +102 -0
  58. data/dry-schema-1.16.0/lib/dry/schema/predicate_inferrer.rb +25 -0
  59. data/dry-schema-1.16.0/lib/dry/schema/predicate_registry.rb +22 -0
  60. data/dry-schema-1.16.0/lib/dry/schema/primitive_inferrer.rb +22 -0
  61. data/dry-schema-1.16.0/lib/dry/schema/processor.rb +213 -0
  62. data/dry-schema-1.16.0/lib/dry/schema/processor_steps.rb +141 -0
  63. data/dry-schema-1.16.0/lib/dry/schema/result.rb +203 -0
  64. data/dry-schema-1.16.0/lib/dry/schema/rule_applier.rb +47 -0
  65. data/dry-schema-1.16.0/lib/dry/schema/step.rb +59 -0
  66. data/dry-schema-1.16.0/lib/dry/schema/trace.rb +114 -0
  67. data/dry-schema-1.16.0/lib/dry/schema/type_container.rb +27 -0
  68. data/dry-schema-1.16.0/lib/dry/schema/type_registry.rb +44 -0
  69. data/dry-schema-1.16.0/lib/dry/schema/types.rb +14 -0
  70. data/dry-schema-1.16.0/lib/dry/schema/types_merger.rb +139 -0
  71. data/dry-schema-1.16.0/lib/dry/schema/value_coercer.rb +36 -0
  72. data/dry-schema-1.16.0/lib/dry/schema/version.rb +7 -0
  73. data/dry-schema-1.16.0/lib/dry/schema.rb +114 -0
  74. data/dry-schema-1.16.0/lib/dry-schema.rb +3 -0
  75. data/mega-sharp-sys.gemspec +11 -0
  76. metadata +114 -0
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dry
4
+ module Schema
5
+ # Key objects used by key maps
6
+ #
7
+ # @api public
8
+ class Key
9
+ extend ::Dry::Core::Cache
10
+
11
+ DEFAULT_COERCER = :itself.to_proc.freeze
12
+
13
+ include ::Dry.Equalizer(:name, :coercer)
14
+
15
+ # @return [Symbol] The key identifier
16
+ attr_reader :id
17
+
18
+ # @return [Symbol, String, Object] The actual key name expected in an input hash
19
+ attr_reader :name
20
+
21
+ # @return [Proc, #call] A key name coercer function
22
+ attr_reader :coercer
23
+
24
+ # @api private
25
+ def self.[](name, **opts)
26
+ new(name, **opts)
27
+ end
28
+
29
+ # @api private
30
+ def self.new(*args, **kwargs)
31
+ fetch_or_store(args, kwargs) { super }
32
+ end
33
+
34
+ # @api private
35
+ def initialize(id, name: id, coercer: DEFAULT_COERCER)
36
+ @id = id
37
+ @name = name
38
+ @coercer = coercer
39
+ end
40
+
41
+ # @api private
42
+ def read(source)
43
+ return unless source.is_a?(::Hash)
44
+
45
+ if source.key?(name)
46
+ yield(source[name])
47
+ elsif source.key?(coerced_name)
48
+ yield(source[coerced_name])
49
+ end
50
+ end
51
+
52
+ # @api private
53
+ def write(source, target)
54
+ read(source) { |value| target[coerced_name] = value }
55
+ end
56
+
57
+ # @api private
58
+ def coercible(&coercer)
59
+ new(coercer: coercer)
60
+ end
61
+
62
+ # @api private
63
+ def stringified
64
+ new(name: name.to_s)
65
+ end
66
+
67
+ # @api private
68
+ def to_dot_notation
69
+ [name.to_s]
70
+ end
71
+
72
+ # @api private
73
+ def new(**new_opts)
74
+ self.class.new(id, name: name, coercer: coercer, **new_opts)
75
+ end
76
+
77
+ # @api private
78
+ def dump
79
+ name
80
+ end
81
+
82
+ private
83
+
84
+ # @api private
85
+ def coerced_name
86
+ @__coerced_name__ ||= coercer[name]
87
+ end
88
+
89
+ # A specialized key type which handles nested hashes
90
+ #
91
+ # @api private
92
+ class Hash < self
93
+ include ::Dry.Equalizer(:name, :members, :coercer)
94
+
95
+ # @api private
96
+ attr_reader :members
97
+
98
+ # @api private
99
+ def initialize(id, members:, **opts)
100
+ super(id, **opts)
101
+ @members = members
102
+ end
103
+
104
+ # @api private
105
+ def read(source)
106
+ super if source.is_a?(::Hash)
107
+ end
108
+
109
+ def write(source, target)
110
+ read(source) { |value|
111
+ target[coerced_name] = value.is_a?(::Hash) ? members.write(value) : value
112
+ }
113
+ end
114
+
115
+ # @api private
116
+ def coercible(&coercer)
117
+ new(coercer: coercer, members: members.coercible(&coercer))
118
+ end
119
+
120
+ # @api private
121
+ def stringified
122
+ new(name: name.to_s, members: members.stringified)
123
+ end
124
+
125
+ # @api private
126
+ def to_dot_notation
127
+ [name].product(members.flat_map(&:to_dot_notation)).map { |e| e.join(DOT) }
128
+ end
129
+
130
+ # @api private
131
+ def dump
132
+ {name => members.map(&:dump)}
133
+ end
134
+ end
135
+
136
+ # A specialized key type which handles nested arrays
137
+ #
138
+ # @api private
139
+ class Array < self
140
+ include ::Dry.Equalizer(:name, :member, :coercer)
141
+
142
+ attr_reader :member
143
+
144
+ # @api private
145
+ def initialize(id, member:, **opts)
146
+ super(id, **opts)
147
+ @member = member
148
+ end
149
+
150
+ # @api private
151
+ def write(source, target)
152
+ read(source) { |value|
153
+ target[coerced_name] =
154
+ if value.is_a?(::Array)
155
+ value.map { |el| el.is_a?(::Hash) ? member.write(el) : el }
156
+ else
157
+ value
158
+ end
159
+ }
160
+ end
161
+
162
+ # @api private
163
+ def coercible(&coercer)
164
+ new(coercer: coercer, member: member.coercible(&coercer))
165
+ end
166
+
167
+ # @api private
168
+ def stringified
169
+ new(name: name.to_s, member: member.stringified)
170
+ end
171
+
172
+ # @api private
173
+ def to_dot_notation
174
+ [:"#{name}[]"].product(member.to_dot_notation).map { |el| el.join(DOT) }
175
+ end
176
+
177
+ # @api private
178
+ def dump
179
+ [name, member.dump]
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/core/cache"
4
+ require "dry/core/equalizer"
5
+
6
+ module Dry
7
+ module Schema
8
+ # Coerces keys in a hash using provided coercer function
9
+ #
10
+ # @api private
11
+ class KeyCoercer
12
+ extend ::Dry::Core::Cache
13
+ include ::Dry::Equalizer(:key_map, :coercer)
14
+
15
+ TO_SYM = :to_sym.to_proc.freeze
16
+
17
+ attr_reader :key_map, :coercer
18
+
19
+ # @api private
20
+ def self.new(*args)
21
+ fetch_or_store(*args) { super }
22
+ end
23
+
24
+ # @api private
25
+ def self.symbolized(*args)
26
+ new(*args, &TO_SYM)
27
+ end
28
+
29
+ # @api private
30
+ def initialize(key_map, &)
31
+ @key_map = key_map.coercible(&)
32
+ end
33
+
34
+ # @api private
35
+ def call(result)
36
+ key_map.write(result.to_h)
37
+ end
38
+ alias_method :[], :call
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/schema/constants"
4
+
5
+ module Dry
6
+ module Schema
7
+ # Represents a list of keys defined by the DSL
8
+ #
9
+ # KeyMap objects expose an API for introspecting schema keys and the ability
10
+ # to rebuild an input hash using configured coercer function.
11
+ #
12
+ # Instances of this class are used as the very first step by the schema processors.
13
+ #
14
+ # @api public
15
+ class KeyMap
16
+ extend ::Dry::Core::Cache
17
+
18
+ include ::Dry.Equalizer(:keys)
19
+ include ::Enumerable
20
+
21
+ # @return [Array<Key>] A list of defined key objects
22
+ attr_reader :keys
23
+
24
+ # Coerce a list of key specs into a key map
25
+ #
26
+ # @example
27
+ # KeyMap[:id, :name]
28
+ # KeyMap[:title, :artist, tags: [:name]]
29
+ # KeyMap[:title, :artist, [:tags]]
30
+ #
31
+ # @return [KeyMap]
32
+ #
33
+ # @api public
34
+ def self.[](*keys)
35
+ new(keys)
36
+ end
37
+
38
+ # Build new, or returned a cached instance of a key map
39
+ #
40
+ # @param [Array<Symbol>, Array, Hash<Symbol=>Array>] args
41
+ #
42
+ # @return [KeyMap]
43
+ def self.new(*args)
44
+ fetch_or_store(*args) { super }
45
+ end
46
+
47
+ # Set key objects
48
+ #
49
+ # @api private
50
+ def initialize(keys)
51
+ @keys = keys.map { |key|
52
+ case key
53
+ when Hash
54
+ root, rest = key.flatten
55
+ Key::Hash[root, members: KeyMap[*rest]]
56
+ when Array
57
+ root, rest = key
58
+ Key::Array[root, member: KeyMap[*rest]]
59
+ when Key
60
+ key
61
+ else
62
+ Key[key]
63
+ end
64
+ }
65
+ end
66
+
67
+ # Write a new hash based on the source hash
68
+ #
69
+ # @param [Hash] source The source hash
70
+ # @param [Hash] target The target hash
71
+ #
72
+ # @return [Hash]
73
+ #
74
+ # @api public
75
+ def write(source, target = EMPTY_HASH.dup)
76
+ each { |key| key.write(source, target) }
77
+ target
78
+ end
79
+
80
+ # Return a new key map that is configured to coerce keys using provided coercer function
81
+ #
82
+ # @return [KeyMap]
83
+ #
84
+ # @api public
85
+ def coercible(&coercer)
86
+ self.class.new(map { |key| key.coercible(&coercer) })
87
+ end
88
+
89
+ # Return a new key map with stringified keys
90
+ #
91
+ # A stringified key map is suitable for reading hashes with string keys
92
+ #
93
+ # @return [KeyMap]
94
+ #
95
+ # @api public
96
+ def stringified
97
+ self.class.new(map(&:stringified))
98
+ end
99
+
100
+ # @api private
101
+ def to_dot_notation
102
+ @to_dot_notation ||= map(&:to_dot_notation).flatten
103
+ end
104
+
105
+ # Iterate over keys
106
+ #
107
+ # @api public
108
+ def each(&)
109
+ keys.each(&)
110
+ end
111
+
112
+ # Return a new key map merged with the provided one
113
+ #
114
+ # @param [KeyMap, Array] other Either a key map or an array with key specs
115
+ #
116
+ # @return [KeyMap]
117
+ def +(other)
118
+ self.class.new(keys + other.to_a)
119
+ end
120
+
121
+ # Return a string representation of a key map
122
+ #
123
+ # @return [String]
124
+ def inspect
125
+ "#<#{self.class}[#{keys.map(&:dump).map(&:inspect).join(", ")}]>"
126
+ end
127
+
128
+ # Dump keys to their spec format
129
+ #
130
+ # @return [Array]
131
+ def dump
132
+ keys.map(&:dump)
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/initializer"
4
+ require "dry/schema/constants"
5
+
6
+ module Dry
7
+ module Schema
8
+ # @api private
9
+ class KeyValidator
10
+ extend ::Dry::Initializer
11
+
12
+ MULTI_INDEX_REGEX = /(\[\d+\])+/
13
+ INDEX_REGEX = /\[\d+\]/
14
+ DIGIT_REGEX = /\A\d+\z/
15
+ BRACKETS = "[]"
16
+
17
+ # @api private
18
+ option :key_map
19
+
20
+ # @api private
21
+ def call(result)
22
+ input = result.to_h
23
+
24
+ input_paths = key_paths(input)
25
+ key_paths = key_map.to_dot_notation.sort
26
+
27
+ input_paths.each do |path|
28
+ error_path = validate_path(key_paths, path)
29
+
30
+ next unless error_path
31
+
32
+ result.add_error([:unexpected_key, [error_path, input]])
33
+ end
34
+
35
+ result
36
+ end
37
+
38
+ private
39
+
40
+ # @api private
41
+ def validate_path(key_paths, path)
42
+ if path[MULTI_INDEX_REGEX]
43
+ key = path.gsub(MULTI_INDEX_REGEX, BRACKETS)
44
+ if none_key_paths_match?(key_paths, key)
45
+ arr = path.gsub(INDEX_REGEX) { ".#{_1[1...-1]}" }
46
+ arr.split(DOT).map { DIGIT_REGEX.match?(_1) ? Integer(_1, 10) : _1.to_sym }
47
+ end
48
+ elsif none_key_paths_match?(key_paths, path)
49
+ path
50
+ end
51
+ end
52
+
53
+ # @api private
54
+ def none_key_paths_match?(key_paths, path)
55
+ !any_key_paths_match?(key_paths, path)
56
+ end
57
+
58
+ # @api private
59
+ def any_key_paths_match?(key_paths, path)
60
+ find_path(key_paths, path, false) ||
61
+ find_path(key_paths, path + DOT, true) ||
62
+ find_path(key_paths, path + BRACKETS, true)
63
+ end
64
+
65
+ # @api private
66
+ def find_path(key_paths, path, prefix_match)
67
+ key = key_paths.bsearch { |key_path| key_path >= path }
68
+ prefix_match ? key&.start_with?(path) : key == path
69
+ end
70
+
71
+ # @api private
72
+ def key_paths(hash)
73
+ hash.flat_map { |key, value|
74
+ case value
75
+ when ::Hash
76
+ if value.empty?
77
+ [key.to_s]
78
+ else
79
+ [key].product(key_paths(hash[key])).map { _1.join(DOT) }
80
+ end
81
+ when ::Array
82
+ hashes_or_arrays = hashes_or_arrays(value)
83
+
84
+ if hashes_or_arrays.empty?
85
+ [key.to_s]
86
+ else
87
+ traverse_array(value).map { |sub_path| [key, sub_path].join("") }
88
+ end
89
+ else
90
+ key.to_s
91
+ end
92
+ }
93
+ end
94
+
95
+ # @api private
96
+ def hashes_or_arrays(xs)
97
+ xs.select { |x|
98
+ (x.is_a?(::Array) || x.is_a?(::Hash)) && !x.empty?
99
+ }
100
+ end
101
+
102
+ # @api private
103
+ def traverse_array(arr)
104
+ arr.each_with_index.flat_map do |el, idx|
105
+ case el
106
+ when ::Hash
107
+ key_paths(el).map { ["[#{idx}]", *_1].join(DOT) }
108
+ when ::Array
109
+ traverse_array(el).map { ["[#{idx}]", *_1].join("") }
110
+ else
111
+ []
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dry
4
+ module Schema
5
+ module Macros
6
+ # Macro used to specify predicates for each element of an array
7
+ #
8
+ # @api private
9
+ class Array < DSL
10
+ # @api private
11
+ # rubocop: disable Metrics/PerceivedComplexity
12
+ # rubocop: disable Metrics/AbcSize
13
+ def value(*args, **opts, &block)
14
+ type(:array)
15
+
16
+ extract_type_spec(args, set_type: false) do |*predicates, type_spec:, type_rule:|
17
+ type(schema_dsl.array[type_spec]) if type_spec
18
+
19
+ is_hash_block = type_spec.equal?(:hash)
20
+
21
+ if predicates.any? || opts.any? || !is_hash_block
22
+ super(
23
+ *predicates, type_spec: type_spec, type_rule: type_rule, **opts,
24
+ &(is_hash_block ? nil : block)
25
+ )
26
+ end
27
+
28
+ is_op = args.size.equal?(2) && args[1].is_a?(Logic::Operations::Abstract)
29
+
30
+ if is_hash_block && !is_op
31
+ hash(&block)
32
+ elsif is_op
33
+ hash = Value.new(schema_dsl: schema_dsl.new, name: name).hash(args[1])
34
+
35
+ trace.captures.concat(hash.trace.captures)
36
+
37
+ type(schema_dsl.types[name].of(hash.schema_dsl.types[name]))
38
+ end
39
+ end
40
+
41
+ self
42
+ end
43
+ # rubocop: enable Metrics/AbcSize
44
+ # rubocop: enable Metrics/PerceivedComplexity
45
+
46
+ # @api private
47
+ def to_ast(*)
48
+ [:and, [trace.array?.to_ast, [:each, trace.to_ast]]]
49
+ end
50
+ alias_method :ast, :to_ast
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/initializer"
4
+ require "dry/schema/constants"
5
+
6
+ module Dry
7
+ module Schema
8
+ module Macros
9
+ # Abstract macro class
10
+ #
11
+ # @api private
12
+ class Core
13
+ extend Dry::Initializer
14
+
15
+ # @api private
16
+ option :name, default: proc {}, optional: true
17
+
18
+ # @api private
19
+ option :compiler, default: proc { Compiler.new }
20
+
21
+ # @api private
22
+ option :schema_dsl, optional: true
23
+
24
+ # @api private
25
+ option :trace, default: proc { Trace.new(schema_dsl&.compiler || Compiler.new) }
26
+
27
+ # @api private
28
+ def new(**options)
29
+ self.class.new(name: name, compiler: compiler, schema_dsl: schema_dsl, **options)
30
+ end
31
+
32
+ # @api private
33
+ def path
34
+ schema_dsl.path
35
+ end
36
+
37
+ # @api private
38
+ def to_rule
39
+ compiler.visit(to_ast)
40
+ end
41
+
42
+ # @api private
43
+ def to_ast(*)
44
+ trace.to_ast
45
+ end
46
+ alias_method :ast, :to_ast
47
+
48
+ # @api private
49
+ def operation
50
+ raise NotImplementedError
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end