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 +4 -4
- data/lib/remap/base.rb +16 -13
- data/lib/remap/compiler.rb +3 -3
- data/lib/remap/extensions/enumerable.rb +2 -4
- data/lib/remap/extensions/object.rb +2 -2
- data/lib/remap/failure.rb +1 -1
- data/lib/remap/mapper/support/api.rb +1 -1
- data/lib/remap/path/input.rb +1 -1
- data/lib/remap/rule/block.rb +5 -2
- data/lib/remap/rule/map/enum.rb +12 -19
- data/lib/remap/rule/map/required.rb +1 -1
- data/lib/remap/rule/map.rb +2 -2
- data/lib/remap/selector/all.rb +10 -10
- data/lib/remap/selector/index.rb +9 -11
- data/lib/remap/selector/key.rb +9 -11
- data/lib/remap/selector.rb +0 -10
- data/lib/remap/state/extension.rb +98 -97
- data/lib/remap/state.rb +4 -4
- data/lib/remap/types.rb +0 -1
- data/lib/remap.rb +1 -1
- metadata +1 -19
- data/lib/remap/iteration/array.rb +0 -35
- data/lib/remap/iteration/hash.rb +0 -35
- data/lib/remap/iteration/other.rb +0 -18
- data/lib/remap/iteration.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a036948beb3769bca586002c771569e54639a3a60314bac615a8f2dbb25a546b
|
4
|
+
data.tar.gz: 966315eb1929aa681d95d477e72a4545bdc435a4a4e3583d1cec875e8061d479
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
#
|
47
|
+
# IfNotMapper.call(["A", "B", "C"]) # => ["A", "C"]
|
48
48
|
#
|
49
49
|
# @example Maps ["A", "B", "C"] to ["B"]
|
50
|
-
# class
|
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
|
-
#
|
60
|
+
# IfMapper.call(["A", "B", "C"]) # => ["B"]
|
61
61
|
#
|
62
62
|
# @example Maps { a: { b: "A" } } to "A"
|
63
|
-
# class
|
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
|
-
#
|
72
|
-
#
|
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
|
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
|
-
#
|
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
|
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
|
data/lib/remap/compiler.rb
CHANGED
@@ -32,7 +32,7 @@ module Remap
|
|
32
32
|
#
|
33
33
|
# @return [Rule]
|
34
34
|
def self.call(backtrace: caller, &block)
|
35
|
-
unless
|
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
|
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
|
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
|
36
|
+
unless fallback
|
37
37
|
return get(*path, trace: trace) do
|
38
|
-
|
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
|
data/lib/remap/failure.rb
CHANGED
@@ -17,7 +17,7 @@ module Remap
|
|
17
17
|
]
|
18
18
|
end
|
19
19
|
|
20
|
-
failure = attributes.
|
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
|
data/lib/remap/path/input.rb
CHANGED
data/lib/remap/rule/block.rb
CHANGED
@@ -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.
|
30
|
-
|
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
|
data/lib/remap/rule/map/enum.rb
CHANGED
@@ -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 :
|
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
|
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
|
-
|
54
|
-
|
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
|
-
|
70
|
-
|
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
|
-
|
76
|
+
@default = value
|
84
77
|
end
|
85
78
|
end
|
86
79
|
end
|
data/lib/remap/rule/map.rb
CHANGED
@@ -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
|
#
|
data/lib/remap/selector/all.rb
CHANGED
@@ -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
|
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(
|
29
|
-
unless
|
26
|
+
def call(state, &block)
|
27
|
+
unless block
|
30
28
|
raise ArgumentError, "All selector requires an iteration block"
|
31
29
|
end
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
31
|
+
value = state.fetch(:value) do
|
32
|
+
return state
|
33
|
+
end
|
37
34
|
|
38
|
-
|
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
|
data/lib/remap/selector/index.rb
CHANGED
@@ -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
|
32
|
+
unless block
|
35
33
|
raise ArgumentError, "The index selector requires an iteration block"
|
36
34
|
end
|
37
35
|
|
38
|
-
state.
|
39
|
-
requirement[array] do
|
40
|
-
s.fatal!("Expected an array")
|
41
|
-
end
|
36
|
+
array = state.fetch(:value) { return state }
|
42
37
|
|
43
|
-
|
44
|
-
|
45
|
-
|
38
|
+
unless array.is_a?(Array)
|
39
|
+
state.fatal!("Expected an array got %s", array.class)
|
40
|
+
end
|
46
41
|
|
47
|
-
|
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
|
data/lib/remap/selector/key.rb
CHANGED
@@ -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
|
29
|
+
unless block
|
32
30
|
raise ArgumentError, "The key selector requires an iteration block"
|
33
31
|
end
|
34
32
|
|
35
|
-
state.
|
36
|
-
requirement[hash] do
|
37
|
-
s.fatal!("Expected hash")
|
38
|
-
end
|
33
|
+
hash = state.fetch(:value) { return state }
|
39
34
|
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
unless hash.is_a?(Hash)
|
36
|
+
state.fatal!("Expected hash got %s", hash.class)
|
37
|
+
end
|
43
38
|
|
44
|
-
|
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
|
data/lib/remap/selector.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
148
|
+
merge(other) do |key, value1, value2|
|
134
149
|
case [key, value1, value2]
|
135
|
-
in [
|
136
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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:
|
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
|
-
|
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
|
-
|
202
|
-
|
203
|
-
|
204
|
-
in [{
|
205
|
-
merge(
|
206
|
-
in [{
|
207
|
-
merge(
|
208
|
-
in [{path:}, {
|
209
|
-
merge(path:
|
210
|
-
in [{path:}, {
|
211
|
-
merge(path: path + [
|
212
|
-
in [{
|
213
|
-
merge(
|
214
|
-
in [{
|
215
|
-
merge(
|
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
|
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
|
-
|
285
|
-
|
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
|
-
|
288
|
-
ignore!(
|
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:
|
35
|
-
notices:
|
36
|
-
path:
|
34
|
+
fatal_ids: [],
|
35
|
+
notices: [],
|
36
|
+
path: [],
|
37
37
|
options: options,
|
38
|
-
ids:
|
38
|
+
ids: [],
|
39
39
|
mapper: mapper,
|
40
40
|
values: value,
|
41
41
|
value: value,
|
data/lib/remap/types.rb
CHANGED
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.
|
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
|
data/lib/remap/iteration/hash.rb
DELETED
@@ -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
|
data/lib/remap/iteration.rb
DELETED
@@ -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
|