remap 2.2.46 → 2.2.50

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71b1a0f8a9cb714d568939ace38b13d053e4c1ddf9131a6040630ff4a1479e4a
4
- data.tar.gz: fe768a12f868c085839145d28a609a707c4aacb10a18c16e2276e51b23de0fb5
3
+ metadata.gz: a036948beb3769bca586002c771569e54639a3a60314bac615a8f2dbb25a546b
4
+ data.tar.gz: 966315eb1929aa681d95d477e72a4545bdc435a4a4e3583d1cec875e8061d479
5
5
  SHA512:
6
- metadata.gz: 2f5f657a29f997cf1161eda204a2ddd38f1c6dcc991c8467732d367bc31302c7bafd1e05f5a7655cc5ef46dea5498b9caec6fb9d75d2bd1e9aa5c7f34f7a8ec9
7
- data.tar.gz: 9263defd99a669a7bcee25381df7a74698cb2ab691b5a2cf22e7cfdb83a8898956b1a17e329e7560e920ad762093822b85c40587dd6bdcf77ab2433188857474
6
+ metadata.gz: f9afa516dd3d8248b714744598c847d04525f1d2d0e0f320128c6b785281b0a40e93d1b444cca6b4d1b6199bdb85dffa5fe4cda1c1d9ef97ec58f348a4994271
7
+ data.tar.gz: 72c2bfaaecc2553b3097f5b464cb03772314dab2127b5154d64b6e99e7e0c028ccba987c94acda788c7fa9229f48a626c895d558a6a974d8cbf95ae16b2d7ea5
data/lib/remap/base.rb CHANGED
@@ -34,33 +34,33 @@ module Remap
34
34
  # Mapper.call({}) # => { api_key: "ABC-123" }
35
35
  #
36
36
  # @example Maps ["A", "B", "C"] to ["A", "C"]
37
- # class Mapper < Remap::Base
37
+ # class IfNotMapper < Remap::Base
38
38
  # define do
39
39
  # each do
40
- # map?.if_not do
40
+ # map?.if_not do |value|
41
41
  # value.include?("B")
42
42
  # end
43
43
  # end
44
44
  # end
45
45
  # end
46
46
  #
47
- # Mapper.call(["A", "B", "C"]) # => ["A", "C"]
47
+ # IfNotMapper.call(["A", "B", "C"]) # => ["A", "C"]
48
48
  #
49
49
  # @example Maps ["A", "B", "C"] to ["B"]
50
- # class Mapper < Remap::Base
50
+ # class IfMapper < Remap::Base
51
51
  # define do
52
52
  # each do
53
- # map?.if do
53
+ # map?.if do |value|
54
54
  # value.include?("B")
55
55
  # end
56
56
  # end
57
57
  # end
58
58
  # end
59
59
  #
60
- # Mapper.call(["A", "B", "C"]) # => ["B"]
60
+ # IfMapper.call(["A", "B", "C"]) # => ["B"]
61
61
  #
62
62
  # @example Maps { a: { b: "A" } } to "A"
63
- # class Mapper < Remap::Base
63
+ # class EnumMapper < Remap::Base
64
64
  # define do
65
65
  # map(:a, :b).enum do
66
66
  # value "A", "B"
@@ -68,11 +68,11 @@ module Remap
68
68
  # end
69
69
  # end
70
70
  #
71
- # Mapper.call({ a: { b: "A" } }) # => "A"
72
- # Mapper.call({ a: { b: "B" } }) # => "B"
71
+ # EnumMapper.call({ a: { b: "A" } }) # => "A"
72
+ # EnumMapper.call({ a: { b: "B" } }) # => "B"
73
73
  #
74
74
  # @example Map { people: [{ name: "John" }] } to { names: ["John"] }
75
- # class Mapper < Remap::Base
75
+ # class PeopleMapper < Remap::Base
76
76
  # define do
77
77
  # map :people, to: :names do
78
78
  # each do
@@ -82,12 +82,12 @@ module Remap
82
82
  # end
83
83
  # end
84
84
  #
85
- # Mapper.call({ people: [{ name: "John" }] }) # => { names: ["John"] }
85
+ # PeopleMapper.call({ people: [{ name: "John" }] }) # => { names: ["John"] }
86
86
  #
87
87
  # @example Map "Hello" to "Hello!"
88
88
  # class HelloMapper < Remap::Base
89
89
  # define do
90
- # map.adjust do
90
+ # map.adjust do |value|
91
91
  # "#{value}!"
92
92
  # end
93
93
  # end
@@ -105,6 +105,7 @@ module Remap
105
105
  # Mapper.call([1, 2, 3]) # => 2
106
106
  class Base < Mapper
107
107
  include ActiveSupport::Configurable
108
+ include Dry::Core::Memoizable
108
109
  include Dry::Core::Constants
109
110
  include Catchable
110
111
  extend Mapper::API
@@ -239,7 +240,7 @@ module Remap
239
240
  # @return [void]
240
241
  # rubocop:disable Layout/LineLength
241
242
  def self.define(target = Nothing, method: :new, strategy: :argument, backtrace: caller, &context)
242
- unless block_given?
243
+ unless context
243
244
  raise ArgumentError, "#{self}.define requires a block"
244
245
  end
245
246
 
@@ -318,5 +319,7 @@ module Remap
318
319
  def validation
319
320
  Contract.call(attributes: attributes, contract: contract, options: options, rules: rules)
320
321
  end
322
+
323
+ memoize :validation
321
324
  end
322
325
  end
@@ -32,7 +32,7 @@ module Remap
32
32
  #
33
33
  # @return [Rule]
34
34
  def self.call(backtrace: caller, &block)
35
- unless block_given?
35
+ unless block
36
36
  return Rule::VOID
37
37
  end
38
38
 
@@ -317,7 +317,7 @@ module Remap
317
317
  # @return [Rule::Each]]
318
318
  # @raise [ArgumentError] if no block given
319
319
  def each(backtrace: caller, &block)
320
- unless block_given?
320
+ unless block
321
321
  raise ArgumentError, "#each requires a block"
322
322
  end
323
323
 
@@ -350,7 +350,7 @@ module Remap
350
350
  # @return [Rule::Wrap]
351
351
  # @raise [ArgumentError] if type is not :array
352
352
  def wrap(type, backtrace: caller, &block)
353
- unless block_given?
353
+ unless block
354
354
  raise ArgumentError, "#wrap requires a block"
355
355
  end
356
356
 
@@ -33,15 +33,13 @@ module Remap
33
33
 
34
34
  key = path.first
35
35
 
36
- unless block_given?
36
+ unless fallback
37
37
  return get(*path, trace: trace) do
38
- raise PathError, trace + [key]
38
+ throw :ignore, trace + [key]
39
39
  end
40
40
  end
41
41
 
42
42
  fetch(key, &fallback).get(*path[1..], trace: trace + [key], &fallback)
43
- rescue TypeError
44
- raise PathError, trace + [key]
45
43
  end
46
44
  end
47
45
  end
@@ -38,9 +38,9 @@ module Remap
38
38
  def get(*path, trace: [], &fallback)
39
39
  return self if path.empty?
40
40
 
41
- unless block_given?
41
+ unless fallback
42
42
  return get(*path, trace: trace) do
43
- raise PathError, trace
43
+ throw :ignore, trace + path
44
44
  end
45
45
  end
46
46
 
data/lib/remap/failure.rb CHANGED
@@ -17,7 +17,7 @@ module Remap
17
17
  ]
18
18
  end
19
19
 
20
- failure = attributes.deep_merge(other.attributes) do |key, value1, value2|
20
+ failure = attributes.merge(other.attributes) do |key, value1, value2|
21
21
  case [key, value1, value2]
22
22
  in [:failures | :notices, Array, Array]
23
23
  value1 + value2
@@ -22,7 +22,7 @@ module Remap
22
22
  #
23
23
  # @return [Any, T]
24
24
  def call(input, backtrace: caller, **options, &error)
25
- unless block_given?
25
+ unless error
26
26
  return call(input, **options) do |failure|
27
27
  raise failure.exception(backtrace)
28
28
  end
@@ -25,7 +25,7 @@ module Remap
25
25
  #
26
26
  # @return [State]
27
27
  def call(state, &iterator)
28
- unless block_given?
28
+ unless iterator
29
29
  raise ArgumentError, "Input path requires an iterator block"
30
30
  end
31
31
 
@@ -26,8 +26,11 @@ module Remap
26
26
  s2 = state.set(fatal_id: fatal_id)
27
27
 
28
28
  catch_ignored(s1) do |s3, id:|
29
- rules.reduce(s3) do |s4, rule|
30
- s5 = rule.call(s2)
29
+ states = rules.map do |rule|
30
+ rule.call(s2)
31
+ end
32
+
33
+ states.reduce(s3) do |s4, s5|
31
34
  s6 = s5.set(id: id)
32
35
  s4.combine(s6)
33
36
  end
@@ -4,13 +4,9 @@ module Remap
4
4
  class Rule
5
5
  class Map
6
6
  class Enum < Proxy
7
- include Dry::Monads[:maybe]
8
-
9
7
  # @return [Hash]
10
- option :mappings, default: -> { Hash.new { default } }
11
-
12
- # @return [Maybe]
13
- option :default, default: -> { None() }
8
+ option :table, default: -> { {} }
9
+ option :default, default: -> { Undefined }
14
10
 
15
11
  alias execute instance_eval
16
12
 
@@ -37,7 +33,7 @@ module Remap
37
33
  new.tap { _1.execute(&block) }
38
34
  end
39
35
 
40
- # Translates key into a value using predefined mappings
36
+ # Translates key into a value using predefined table
41
37
  #
42
38
  # @param key [#hash]
43
39
  #
@@ -50,24 +46,21 @@ module Remap
50
46
  return get(key) { raise Error, _1 }
51
47
  end
52
48
 
53
- self[key].bind { return _1 }.or do
54
- error["Enum key [#{key}] not found among [#{mappings.keys.inspect}]"]
49
+ table.fetch(key) do
50
+ unless default == Undefined
51
+ return default
52
+ end
53
+
54
+ error["Enum key [#{key}] not found among [#{table.keys.inspect}]"]
55
55
  end
56
56
  end
57
57
  alias call get
58
58
 
59
- # @return [Maybe]
60
- def [](key)
61
- mappings[key]
62
- end
63
-
64
59
  # @return [void]
65
60
  def from(*keys, to:)
66
- value = Some(to)
67
-
68
61
  keys.each do |key|
69
- mappings[key] = value
70
- mappings[to] = value
62
+ table[key] = to
63
+ table[to] = to
71
64
  end
72
65
  end
73
66
 
@@ -80,7 +73,7 @@ module Remap
80
73
 
81
74
  # @return [void]
82
75
  def otherwise(value)
83
- mappings.default = Some(value)
76
+ @default = value
84
77
  end
85
78
  end
86
79
  end
@@ -16,7 +16,7 @@ module Remap
16
16
  end
17
17
 
18
18
  s3 = s2.then(&path.output)
19
- s4 = s3.set(path: state.path)
19
+ s4 = s3.merge(path: state.path)
20
20
 
21
21
  s4.except(:key)
22
22
  end
@@ -117,7 +117,7 @@ module Remap
117
117
  # Keeps map, only if block is true
118
118
  #
119
119
  # @example Keep if value contains "A"
120
- # map = Remap::Rule::Map::Optional.call(backtrace: caller).if do
120
+ # map = Remap::Rule::Map::Optional.call(backtrace: caller).if do |value|
121
121
  # value.include?("A")
122
122
  # end
123
123
  #
@@ -145,7 +145,7 @@ module Remap
145
145
  #
146
146
 
147
147
  # @example Keep unless value contains "A"
148
- # map = Remap::Rule::Map::Optional.new(backtrace: caller).if_not do
148
+ # map = Remap::Rule::Map::Optional.new(backtrace: caller).if_not do |value|
149
149
  # value.include?("A")
150
150
  # end
151
151
  #
@@ -15,28 +15,28 @@ module Remap
15
15
  # end
16
16
  # result.fetch(:value) # => [Hash, Hash]
17
17
  class All < Concrete
18
- requirement Types::Enumerable
19
-
20
18
  # Iterates over state and passes each value to block
21
19
  #
22
- # @param outer_state [State<Enumerable<T>>]
20
+ # @param state [State<Enumerable<T>>]
23
21
  #
24
22
  # @yieldparam [State<T>]
25
23
  # @yieldreturn [State<U>]
26
24
  #
27
25
  # @return [State<U>]
28
- def call(outer_state, &block)
29
- unless block_given?
26
+ def call(state, &block)
27
+ unless block
30
28
  raise ArgumentError, "All selector requires an iteration block"
31
29
  end
32
30
 
33
- outer_state.bind(quantifier: "*") do |enum, state|
34
- requirement[enum] do
35
- state.fatal!("Expected enumerable")
36
- end
31
+ value = state.fetch(:value) do
32
+ return state
33
+ end
37
34
 
38
- state.map(&block)
35
+ unless value.is_a?(Enumerable)
36
+ state.fatal!("Not an enumerator")
39
37
  end
38
+
39
+ state.map(&block)
40
40
  end
41
41
  end
42
42
  end
@@ -20,8 +20,6 @@ module Remap
20
20
  # @return [Integer]
21
21
  attribute :index, Integer
22
22
 
23
- requirement Types::Array
24
-
25
23
  # Selects the {#index}th element from state and passes it to block
26
24
  #
27
25
  # @param state [State<Array<T>>]
@@ -31,21 +29,21 @@ module Remap
31
29
  #
32
30
  # @return [State<U>]
33
31
  def call(state, &block)
34
- unless block_given?
32
+ unless block
35
33
  raise ArgumentError, "The index selector requires an iteration block"
36
34
  end
37
35
 
38
- state.bind(index: index) do |array, s|
39
- requirement[array] do
40
- s.fatal!("Expected an array")
41
- end
36
+ array = state.fetch(:value) { return state }
42
37
 
43
- element = array.fetch(index) do
44
- s.ignore!("Index not found")
45
- end
38
+ unless array.is_a?(Array)
39
+ state.fatal!("Expected an array got %s", array.class)
40
+ end
46
41
 
47
- state.set(element, index: index).then(&block)
42
+ value = array.fetch(index) do
43
+ state.ignore!("Index [%s] (%s) not found", index, index.class)
48
44
  end
45
+
46
+ state.set(value, index: index).then(&block)
49
47
  end
50
48
  end
51
49
  end
@@ -17,8 +17,6 @@ module Remap
17
17
  # @return [#hash
18
18
  attribute :key, Types::Key
19
19
 
20
- requirement Types::Hash
21
-
22
20
  # Selects {#key} from state and passes it to block
23
21
  #
24
22
  # @param state [State<Hash<K, V>>]
@@ -28,21 +26,21 @@ module Remap
28
26
  #
29
27
  # @return [State<U>]
30
28
  def call(state, &block)
31
- unless block_given?
29
+ unless block
32
30
  raise ArgumentError, "The key selector requires an iteration block"
33
31
  end
34
32
 
35
- state.bind(key: key) do |hash, s|
36
- requirement[hash] do
37
- s.fatal!("Expected hash")
38
- end
33
+ hash = state.fetch(:value) { return state }
39
34
 
40
- value = hash.fetch(key) do
41
- s.ignore!("Key not found")
42
- end
35
+ unless hash.is_a?(Hash)
36
+ state.fatal!("Expected hash got %s", hash.class)
37
+ end
43
38
 
44
- state.set(value, key: key).then(&block)
39
+ value = hash.fetch(key) do
40
+ state.ignore!("Key [%s] (%s) not found", key, key.class)
45
41
  end
42
+
43
+ state.set(value, key: key).then(&block)
46
44
  end
47
45
  end
48
46
  end
@@ -4,9 +4,6 @@ module Remap
4
4
  # Defines how a path element, or selector
5
5
  # Specifies how a value is extracted from a state
6
6
  class Selector < Dry::Interface
7
- defines :requirement, type: Types::Any.constrained(type: Dry::Types::Type)
8
- requirement Types::Any
9
-
10
7
  # Selects value from state, package it as a state and passes it to block
11
8
  #
12
9
  # @param state [State]
@@ -20,12 +17,5 @@ module Remap
20
17
  def call(state)
21
18
  raise NotImplementedError, "#{self.class}#call not implemented"
22
19
  end
23
-
24
- private
25
-
26
- # @return [Dry::Types::Type]
27
- def requirement
28
- self.class.requirement
29
- end
30
20
  end
31
21
  end
@@ -46,11 +46,7 @@ module Remap
46
46
  # @returns [Hash] a hash containing the given path
47
47
  # @raise Europace::Error when path doesn't exist
48
48
  def only(*path)
49
- path.reduce(EMPTY_HASH) do |hash, key|
50
- next hash unless key?(key)
51
-
52
- hash.deep_merge(key => fetch(key))
53
- end
49
+ dup.extract!(*path)
54
50
  end
55
51
 
56
52
  # @see #notice
@@ -112,11 +108,30 @@ module Remap
112
108
  #
113
109
  # @return [State]
114
110
  def map(&block)
115
- bind do |value, state|
116
- Iteration.call(state: state, value: value).call do |other, **options|
117
- state.set(other, **options).then(&block)
118
- end.except(:index, :element, :key)
111
+ result = case self
112
+ in { value: Array => array }
113
+ array.each_with_index.each_with_object([]) do |(value, index), array|
114
+ s1 = block[set(value, index: index)]
115
+
116
+ if s1.key?(:value)
117
+ array << s1[:value]
118
+ end
119
+ end
120
+ in { value: Hash => hash }
121
+ hash.each_with_object({}) do |(key, value), acc|
122
+ s1 = block[set(value, key: key)]
123
+
124
+ if s1.key?(:value)
125
+ acc[key] = s1[:value]
126
+ end
127
+ end
128
+ in { value: }
129
+ fatal!("Expected an enumerable got %s", value.class)
130
+ else
131
+ return self
119
132
  end
133
+
134
+ set(result)
120
135
  end
121
136
 
122
137
  # @return [String]
@@ -130,10 +145,14 @@ module Remap
130
145
  #
131
146
  # @return [State]
132
147
  def combine(other)
133
- deep_merge(other) do |key, value1, value2|
148
+ merge(other) do |key, value1, value2|
134
149
  case [key, value1, value2]
135
- in [:value, Array => list1, Array => list2]
136
- list1 + list2
150
+ in [_, Hash => left, Hash => right]
151
+ left.merge(right)
152
+ in [:ids | :fatal_ids, _, right]
153
+ right
154
+ in [_, Array => left, Array => right]
155
+ left + right
137
156
  in [:value, left, right]
138
157
  other.fatal!(
139
158
  "Could not merge [%s] (%s) with [%s] (%s)",
@@ -142,15 +161,6 @@ module Remap
142
161
  right.formatted,
143
162
  right.class
144
163
  )
145
- in [:notices, Array => n1, Array => n2]
146
- n1 + n2
147
- in [:ids, i1, i2] if i1.all? { i2.include?(_1) }
148
- i2
149
- in [:ids, i1, i2] if i2.all? { i1.include?(_1) }
150
- i1
151
- in [:ids, i1, i2]
152
- other.fatal!("Could not merge #ids [%s] (%s) with [%s] (%s)", i1, i1.class, i2,
153
- i2.class)
154
164
  in [Symbol, _, value]
155
165
  value
156
166
  end
@@ -160,31 +170,39 @@ module Remap
160
170
  # @todo Merge with {#remove_fatal_id}
161
171
  # @return [State]
162
172
  def remove_id
163
- case self
173
+ state = dup
174
+
175
+ case state
164
176
  in { ids: [], id: }
165
- except(:id)
177
+ state.except!(:id)
166
178
  in { ids:, id: }
167
- merge(ids: ids[1...], id: ids[0])
179
+ state.merge!(ids: ids[1...], id: ids[0])
168
180
  in { ids: [] }
169
- self
181
+ state
170
182
  in { ids: }
171
183
  raise ArgumentError, "[BUG] #ids for state are set, but not #id: %s" % formatted
172
- end._
184
+ end
185
+
186
+ state
173
187
  end
174
188
 
175
189
  # @todo Merge with {#remove_id}
176
190
  # @return [State]
177
191
  def remove_fatal_id
178
- case self
192
+ state = dup
193
+
194
+ case state
179
195
  in { fatal_ids: [], fatal_id: }
180
- except(:fatal_id)
181
- in { fatal_ids: ids, fatal_id: id }
182
- merge(fatal_ids: ids[1...], fatal_id: ids[0])
196
+ state.except!(:fatal_id)
197
+ in { fatal_ids: ids, fatal_id: }
198
+ state.merge!(fatal_ids: ids[1...], fatal_id: ids[0])
183
199
  in { fatal_ids: [] }
184
- self
200
+ state
185
201
  in { fatal_ids: }
186
202
  raise ArgumentError, "[BUG] #ids for state are set, but not #id: %s" % formatted
187
- end._
203
+ end
204
+
205
+ state
188
206
  end
189
207
 
190
208
  # Creates a new state with params
@@ -198,24 +216,32 @@ module Remap
198
216
  return set(**options, value: value)
199
217
  end
200
218
 
201
- case [self, options]
202
- in [{notices:}, {notice: notice, **rest}]
203
- merge(notices: notices + [notice]).set(**rest)
204
- in [{value:}, {mapper:, **rest}]
205
- merge(scope: value, mapper: mapper).set(**rest)
206
- in [{path:}, {key:, **rest}]
207
- merge(path: path + [key], key: key).set(**rest)
208
- in [{path:}, {index:, value:, **rest}]
209
- merge(path: path + [index], element: value, index: index, value: value).set(**rest)
210
- in [{path:}, {index:, **rest}]
211
- merge(path: path + [index], index: index).set(**rest)
212
- in [{ids:, id: old_id}, {id: new_id, **rest}]
213
- merge(ids: [old_id] + ids, id: new_id).set(**rest)
214
- in [{fatal_ids:, fatal_id: old_id}, {fatal_id: new_id, **rest}]
215
- merge(fatal_ids: [old_id] + fatal_ids, fatal_id: new_id).set(**rest)
219
+ state = dup
220
+
221
+ case [state, options]
222
+ in [{notices:}, {notice: notice}]
223
+ state.merge!(notices: notices + [notice])
224
+ in [{value:}, {mapper:}]
225
+ state.merge!(scope: value, mapper: mapper)
226
+ in [{path: p1}, {path: p2}]
227
+ state.merge!(path: p1 + p2)
228
+ in [{path:}, {key:, value:}]
229
+ state.merge!(path: path + [key], key: key, value: value)
230
+ in [{path:}, {key:}]
231
+ state.merge!(path: path + [key], key: key)
232
+ in [{path:}, {index:, value:}]
233
+ state.merge!(path: path + [index], element: value, index: index, value: value)
234
+ in [{path:}, {index:}]
235
+ state.merge!(path: path + [index], index: index)
236
+ in [{ids:, id: old_id}, {id: new_id}]
237
+ state.merge!(ids: [old_id] + ids, id: new_id)
238
+ in [{fatal_ids:, fatal_id: old_id}, {fatal_id: new_id}]
239
+ state.merge!(fatal_ids: [old_id] + fatal_ids, fatal_id: new_id)
216
240
  else
217
- merge(options)
241
+ state.merge!(options)
218
242
  end
243
+
244
+ state
219
245
  end
220
246
 
221
247
  # Passes {#value} to block, if defined
@@ -235,22 +261,6 @@ module Remap
235
261
  end
236
262
  end
237
263
 
238
- # Creates a failure to be used in {Remap::Base} & {Remap::Mapper}
239
- #
240
- # @param reason [#to_s]
241
- #
242
- # @see State::Schema
243
- #
244
- # @return [Failure]
245
-
246
- # class Failure < Dry::Interface
247
- # attribute :notices, [Notice], min_size: 1
248
- # end
249
-
250
- def failure(reason = Undefined)
251
- raise NotImplementedError, "Not implemented"
252
- end
253
-
254
264
  # Passes {#value} to block, if defined
255
265
  # {options} are combine into the final state
256
266
  #
@@ -262,7 +272,7 @@ module Remap
262
272
  #
263
273
  # @return [Y]
264
274
  def bind(**options, &block)
265
- unless block_given?
275
+ unless block
266
276
  raise ArgumentError, "State#bind requires a block"
267
277
  end
268
278
 
@@ -281,21 +291,33 @@ module Remap
281
291
  #
282
292
  # @return [State<U>]
283
293
  def execute(&block)
284
- bind do |value|
285
- result = context(value).instance_exec(value, &block)
294
+ value = fetch(:value) { return self }
295
+
296
+ path = catch :ignore do
297
+ names = block.parameters.reduce([]) do |acc, (type, name)|
298
+ case type
299
+ in :keyreq
300
+ acc + [name]
301
+ else
302
+ acc
303
+ end
304
+ end
305
+
306
+ n1 = options.only(*names)
307
+ n2 = only(*names)
286
308
 
287
- if result.equal?(Dry::Core::Constants::Undefined)
288
- ignore!("Undefined returned, skipping!")
309
+ result = block[value, **n2, **n1] do |reason|
310
+ return ignore!(reason)
289
311
  end
290
312
 
291
- set(result)
292
- rescue KeyError => e
293
- set(path: path + [e.key]).ignore!(e.message)
294
- rescue IndexError => e
295
- ignore!(e.message)
296
- rescue PathError => e
297
- set(path: path + e.path).ignore!("Undefined path")
313
+ return set(result)
298
314
  end
315
+
316
+ set(path: path).ignore!("Undefined path")
317
+ rescue KeyError => e
318
+ set(path: [e.key]).ignore!(e.message)
319
+ rescue IndexError => e
320
+ ignore!(e.message)
299
321
  end
300
322
 
301
323
  # Passes {#value} to block and returns {self}
@@ -416,27 +438,6 @@ module Remap
416
438
 
417
439
  throw id, remove_id
418
440
  end
419
-
420
- private
421
-
422
- # Creates a context containing {options} and {self}
423
- #
424
- # @param value [Any]
425
- #
426
- # @yieldparam reason [T]
427
- #
428
- # @return [Struct]
429
- def context(value, context: self)
430
- ::Struct.new(*except(:id).keys, *options.keys, :state, keyword_init: true) do
431
- define_method :method_missing do |name, *|
432
- context.fatal!("Method [%s] not defined", name)
433
- end
434
-
435
- define_method(:skip!) do |message = "Manual skip!"|
436
- context.ignore!(message)
437
- end
438
- end.new(**to_hash, **options, value: value, state: self)
439
- end
440
441
  end
441
442
  end
442
443
  end
data/lib/remap/state.rb CHANGED
@@ -31,11 +31,11 @@ module Remap
31
31
  # @return [Hash] A valid state
32
32
  def self.call(value, mapper: Dummy, options: EMPTY_HASH)
33
33
  {
34
- fatal_ids: EMPTY_ARRAY,
35
- notices: EMPTY_ARRAY,
36
- path: EMPTY_ARRAY,
34
+ fatal_ids: [],
35
+ notices: [],
36
+ path: [],
37
37
  options: options,
38
- ids: EMPTY_ARRAY,
38
+ ids: [],
39
39
  mapper: mapper,
40
40
  values: value,
41
41
  value: value,
data/lib/remap/types.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/monads/maybe"
4
3
  require "dry/logic/operations/negation"
5
4
  require "dry/logic"
6
5
 
data/lib/remap.rb CHANGED
@@ -5,11 +5,11 @@ require "active_support/core_ext/enumerable"
5
5
  require "active_support/core_ext/array/wrap"
6
6
  require "active_support/proxy_object"
7
7
 
8
+ require "dry/core/memoizable"
8
9
  require "dry/validation"
9
10
  require "dry/interface"
10
11
  require "dry/schema"
11
12
  require "dry/struct"
12
- require "dry/monads"
13
13
  require "dry/types"
14
14
 
15
15
  require "neatjson"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remap
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.46
4
+ version: 2.2.50
5
5
  platform: ruby
6
6
  authors:
7
7
  - Linus Oleander
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 1.0.3
69
- - !ruby/object:Gem::Dependency
70
- name: dry-monads
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 1.4.0
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 1.4.0
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: dry-schema
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -264,10 +250,6 @@ files:
264
250
  - lib/remap/extensions/object.rb
265
251
  - lib/remap/failure.rb
266
252
  - lib/remap/failure/error.rb
267
- - lib/remap/iteration.rb
268
- - lib/remap/iteration/array.rb
269
- - lib/remap/iteration/hash.rb
270
- - lib/remap/iteration/other.rb
271
253
  - lib/remap/mapper.rb
272
254
  - lib/remap/mapper/and.rb
273
255
  - lib/remap/mapper/binary.rb
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Remap
4
- class Iteration
5
- using State::Extension
6
-
7
- # Implements an array iterator which defines index in state
8
- class Array < Concrete
9
- # @return [Array<T>]
10
- attribute :value, Types::Array, alias: :array
11
-
12
- # @return [State<Array<T>>]
13
- attribute :state, Types::State
14
-
15
- # @see Iteration#map
16
- def call(&block)
17
- array.each_with_index.reduce(init) do |state, (value, index)|
18
- reduce(state, value, index, &block)
19
- end
20
- end
21
-
22
- private
23
-
24
- def init
25
- state.set(EMPTY_ARRAY)
26
- end
27
-
28
- def reduce(state, value, index, &block)
29
- s0 = block[value, index: index]
30
- s1 = s0.set(**state.only(:ids, :fatal_id))
31
- state.combine(s1.fmap { [_1] })
32
- end
33
- end
34
- end
35
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Remap
4
- class Iteration
5
- using State::Extension
6
-
7
- # Implements a hash iterator which defines key in state
8
- class Hash < Concrete
9
- # @return [Hash]
10
- attribute :value, Types::Hash, alias: :hash
11
-
12
- # @return [State<Hash>]
13
- attribute :state, Types::State
14
-
15
- # @see Iteration#map
16
- def call(&block)
17
- hash.reduce(init) do |state, (key, value)|
18
- reduce(state, key, value, &block)
19
- end
20
- end
21
-
22
- private
23
-
24
- def reduce(state, key, value, &block)
25
- s0 = block[value, key: key]
26
- s1 = s0.set(fatal_id: state.fatal_id, ids: state.ids)
27
- state.combine(s1.fmap { { key => _1 } })
28
- end
29
-
30
- def init
31
- state.set(EMPTY_HASH)
32
- end
33
- end
34
- end
35
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Remap
4
- class Iteration
5
- using State::Extension
6
-
7
- # Default iterator which doesn't do anything
8
- class Other < Concrete
9
- attribute :value, Types::Any, alias: :other
10
- attribute :state, Types::State
11
-
12
- # @see Iteration#map
13
- def call(&block)
14
- state.fatal!("Expected an enumerable")
15
- end
16
- end
17
- end
18
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Remap
4
- class Iteration < Dry::Interface
5
- # @return [State<T>]
6
- attribute :state, Types::State
7
-
8
- # @return [T]
9
- attribute :value, Types::Any
10
-
11
- # Maps every element in {#value}
12
- #
13
- # @abstract
14
- #
15
- # @yieldparam element [V]
16
- # @yieldparam key [K, Integer]
17
- # @yieldreturn [Array<V>, Hash<V, K>]
18
- #
19
- # @return [Array<V>, Hash<V, K>]
20
- def call(state)
21
- raise NotImplementedError, "#{self.class}#call not implemented"
22
- end
23
-
24
- order :Hash, :Array, :Other
25
- end
26
- end