depth 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/depth/actions.rb +43 -9
- data/lib/depth/complex_hash.rb +11 -2
- data/lib/depth/traverser.rb +47 -6
- data/lib/depth/version.rb +1 -1
- data/spec/depth/actions_spec.rb +69 -3
- data/spec/depth/enumerable_spec.rb +5 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85d067842e7799d193a25834e13a66d7b8fd7375
|
4
|
+
data.tar.gz: e6af288638c9e95b1a9e3d3fd9a245a05ce17320
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 207ae9111a988453a18d33b25c5ba1d70e0249d655874377de02d4f82b6b30b86b9b57b3778a03052b20b828b0f1bd8f859dd601a765937a5d4dd6b4ac3deba8
|
7
|
+
data.tar.gz: 012ac2126a5aa29cacf5806fef20cc0686378715b708c5decdcf9d57c975ba78b0c90869449476ef94d52e0486721caef036c29eff93f7c17d10b3ef0a121c6c
|
data/lib/depth/actions.rb
CHANGED
@@ -4,28 +4,55 @@ module Depth
|
|
4
4
|
def base
|
5
5
|
raise NoMethodError.new('should be overridden')
|
6
6
|
end
|
7
|
+
|
8
|
+
def next_proc
|
9
|
+
raise NoMethodError.new('should be overridden')
|
10
|
+
end
|
11
|
+
|
12
|
+
def creation_proc
|
13
|
+
raise NoMethodError.new('should be overridden')
|
14
|
+
end
|
15
|
+
|
16
|
+
def key_transformer
|
17
|
+
raise NoMethodError.new('should be overridden')
|
18
|
+
end
|
7
19
|
#:nocov:
|
8
20
|
|
9
21
|
def set(route, value)
|
10
22
|
route = RouteElement.convert_route(route)
|
11
|
-
|
23
|
+
base_traverser = Traverser.new(
|
24
|
+
base, next_proc: next_proc,
|
25
|
+
creation_proc: creation_proc,
|
26
|
+
key_transformer: key_transformer
|
27
|
+
)
|
28
|
+
object = route[0 ... -1].reduce(base_traverser) { |t, route_el|
|
12
29
|
t.next_or_create(route_el.key) { route_el.create }
|
13
30
|
}.object
|
14
|
-
|
31
|
+
original_key = route.last.key
|
32
|
+
transformed_key = key_transformer.call(object, route.last.key)
|
33
|
+
creation_proc.call(object, transformed_key, value, original_key)
|
15
34
|
end
|
16
35
|
|
17
36
|
def find(route, create: false, default: nil)
|
37
|
+
return self if route.empty?
|
18
38
|
route = RouteElement.convert_route(route)
|
19
|
-
|
39
|
+
base_traverser = Traverser.new(
|
40
|
+
base, next_proc: next_proc,
|
41
|
+
creation_proc: creation_proc,
|
42
|
+
key_transformer: key_transformer
|
43
|
+
)
|
44
|
+
parent = route[0 ... -1].reduce(base_traverser) { |t, route_el|
|
20
45
|
if create
|
21
46
|
t.next_or_create(route_el.key) { route_el.create }
|
22
47
|
else
|
23
48
|
t.next(route_el.key)
|
24
49
|
end
|
25
50
|
}.object
|
26
|
-
|
51
|
+
original_key = route.last.key
|
52
|
+
transformed_key = key_transformer.call(parent, route.last.key)
|
53
|
+
object = parent ? next_proc.call(parent, transformed_key, original_key) : nil
|
27
54
|
return object unless object.nil?
|
28
|
-
return parent
|
55
|
+
return creation_proc.call(parent, transformed_key, default, original_key) if create && default
|
29
56
|
default
|
30
57
|
end
|
31
58
|
|
@@ -34,7 +61,8 @@ module Depth
|
|
34
61
|
route = RouteElement.convert_route(route)
|
35
62
|
value = find(route) unless value
|
36
63
|
new_route = (route[0 ... -1] << RouteElement.convert(key))
|
37
|
-
|
64
|
+
# ensure it exists
|
65
|
+
set(new_route, value)
|
38
66
|
old_key = route.last.key
|
39
67
|
return unless old_key != key
|
40
68
|
delete(route)
|
@@ -42,13 +70,19 @@ module Depth
|
|
42
70
|
|
43
71
|
def delete(route)
|
44
72
|
route = RouteElement.convert_route(route)
|
45
|
-
|
73
|
+
base_traverser = Traverser.new(
|
74
|
+
base, next_proc: next_proc,
|
75
|
+
creation_proc: creation_proc,
|
76
|
+
key_transformer: key_transformer
|
77
|
+
)
|
78
|
+
traverser = route[0...-1].reduce(base_traverser) do |t, route_el|
|
46
79
|
t.next(route_el.key)
|
47
80
|
end
|
81
|
+
last_key = key_transformer.call(traverser.object, route.last.key)
|
48
82
|
if traverser.array?
|
49
|
-
traverser.object.delete_at(
|
83
|
+
traverser.object.delete_at(last_key)
|
50
84
|
elsif traverser.hash?
|
51
|
-
traverser.object.delete(
|
85
|
+
traverser.object.delete(last_key)
|
52
86
|
end
|
53
87
|
end
|
54
88
|
end
|
data/lib/depth/complex_hash.rb
CHANGED
@@ -2,10 +2,19 @@ module Depth
|
|
2
2
|
class ComplexHash
|
3
3
|
include Depth::Actions
|
4
4
|
include Depth::Enumeration::Enumerable
|
5
|
-
|
5
|
+
DEFAULT_KEY_TRANSFORMER = proc { |obj, key| key }
|
6
|
+
DEFAULT_NEXT_PROC = proc { |obj, key| obj[key] }
|
7
|
+
DEFAULT_CREATION_PROC = proc { |obj, key, val| obj[key] = val }
|
8
|
+
attr_reader :base, :next_proc, :creation_proc, :key_transformer
|
6
9
|
alias_method :to_h, :base
|
7
|
-
def initialize(base = {}
|
10
|
+
def initialize(base = {},
|
11
|
+
key_transformer: DEFAULT_KEY_TRANSFORMER,
|
12
|
+
next_proc: DEFAULT_NEXT_PROC,
|
13
|
+
creation_proc: DEFAULT_CREATION_PROC)
|
8
14
|
@base = base
|
15
|
+
@next_proc = next_proc
|
16
|
+
@creation_proc = creation_proc
|
17
|
+
@key_transformer = key_transformer
|
9
18
|
end
|
10
19
|
end
|
11
20
|
end
|
data/lib/depth/traverser.rb
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
module Depth
|
2
|
-
class Traverser
|
2
|
+
class Traverser
|
3
|
+
|
4
|
+
attr_reader :object
|
5
|
+
|
6
|
+
def initialize(object,
|
7
|
+
key_transformer:,
|
8
|
+
next_proc:, creation_proc:)
|
9
|
+
@object = object
|
10
|
+
@next_proc = next_proc
|
11
|
+
@creation_proc = creation_proc
|
12
|
+
@key_transformer = key_transformer
|
13
|
+
end
|
14
|
+
|
3
15
|
def array?
|
4
16
|
object.is_a?(Array)
|
5
17
|
end
|
@@ -9,14 +21,43 @@ module Depth
|
|
9
21
|
end
|
10
22
|
|
11
23
|
def next(key_or_index)
|
12
|
-
|
13
|
-
|
24
|
+
original_key = key_or_index
|
25
|
+
key_or_index = key_transformer.call(object, key_or_index)
|
26
|
+
next_object = if object.nil?
|
27
|
+
nil
|
28
|
+
else
|
29
|
+
next_proc.call(object, key_or_index, original_key)
|
30
|
+
end
|
31
|
+
|
32
|
+
Traverser.new(
|
33
|
+
next_object,
|
34
|
+
key_transformer: key_transformer,
|
35
|
+
next_proc: next_proc,
|
36
|
+
creation_proc: creation_proc
|
37
|
+
)
|
14
38
|
end
|
15
39
|
|
16
40
|
def next_or_create(key_or_index, &block)
|
17
|
-
|
18
|
-
|
19
|
-
Traverser.new(
|
41
|
+
original_key = key_or_index
|
42
|
+
key_or_index = key_transformer.call(object, key_or_index)
|
43
|
+
return Traverser.new(
|
44
|
+
nil,
|
45
|
+
key_transformer: key_transformer,
|
46
|
+
next_proc: next_proc,
|
47
|
+
creation_proc: creation_proc
|
48
|
+
) if object.nil?
|
49
|
+
next_object = next_proc.call(object, key_or_index, original_key)
|
50
|
+
creation_proc.call(object, key_or_index, block.call, original_key) if next_object.nil?
|
51
|
+
Traverser.new(
|
52
|
+
# Refetch it to allow for creation
|
53
|
+
next_proc.call(object, key_or_index, original_key),
|
54
|
+
key_transformer: key_transformer,
|
55
|
+
next_proc: next_proc,
|
56
|
+
creation_proc: creation_proc
|
57
|
+
)
|
20
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
attr_reader :next_proc, :creation_proc, :key_transformer
|
21
62
|
end
|
22
63
|
end
|
data/lib/depth/version.rb
CHANGED
data/spec/depth/actions_spec.rb
CHANGED
@@ -6,9 +6,13 @@ module Depth
|
|
6
6
|
let(:actions_class) do
|
7
7
|
Class.new do
|
8
8
|
include Actions
|
9
|
-
attr_reader :base
|
10
|
-
|
9
|
+
attr_reader :base, :next_proc, :creation_proc,
|
10
|
+
:key_transformer
|
11
|
+
def initialize(base, next_proc:, key_transformer:, creation_proc:)
|
11
12
|
@base = base
|
13
|
+
@next_proc = next_proc
|
14
|
+
@creation_proc = creation_proc
|
15
|
+
@key_transformer = key_transformer
|
12
16
|
end
|
13
17
|
end
|
14
18
|
end
|
@@ -24,9 +28,71 @@ module Depth
|
|
24
28
|
]}
|
25
29
|
end
|
26
30
|
|
27
|
-
|
31
|
+
let(:next_proc) { proc { |o, k| o[k] } }
|
32
|
+
let(:creation_proc) { proc { |o, k, v| o[k] = v } }
|
33
|
+
let(:key_transformer) { proc { |_, k| k } }
|
34
|
+
|
35
|
+
subject do
|
36
|
+
actions_class.new(
|
37
|
+
hash, next_proc: next_proc,
|
38
|
+
creation_proc: creation_proc,
|
39
|
+
key_transformer: key_transformer
|
40
|
+
)
|
41
|
+
end
|
28
42
|
|
29
43
|
describe '#set' do
|
44
|
+
context 'with a key transformer' do
|
45
|
+
let(:key_transformer) do
|
46
|
+
proc { |_, k|
|
47
|
+
next(k) if k.to_s !~ /index_/
|
48
|
+
k.gsub(/index_/, '').to_i
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should still work' do
|
53
|
+
route = [['$and', :array], ['index_0', :hash],
|
54
|
+
['#weather', :hash], ['something', :array]]
|
55
|
+
expect do
|
56
|
+
subject.set(route, :test)
|
57
|
+
end.to change { hash['$and'][0]['#weather']['something'] }.to(:test)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with a custom creation proc' do
|
62
|
+
let(:creation_proc) do
|
63
|
+
proc { |o, k, v| o[k] = '2' }
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should let me change the creation proc' do
|
67
|
+
route = [['$and', :array], [0, :hash],
|
68
|
+
['#weather', :hash], ['something', :array]]
|
69
|
+
expect do
|
70
|
+
subject.set(route, :test)
|
71
|
+
end.to change { hash['$and'][0]['#weather']['something'] }.to('2')
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'with a custom next proc' do
|
77
|
+
let(:next_proc) do
|
78
|
+
proc { |obj, key|
|
79
|
+
if(obj.is_a?(Array))
|
80
|
+
obj.at(key)
|
81
|
+
else
|
82
|
+
obj.fetch(key)
|
83
|
+
end
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should allow me to change how I traverse the route' do
|
88
|
+
route = [['$and', :array], [0, :hash],
|
89
|
+
['#weather', :hash], ['something', :array]]
|
90
|
+
expect do
|
91
|
+
subject.set(route, :test)
|
92
|
+
end.to change { hash['$and'][0]['#weather']['something'] }.to(:test)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
30
96
|
it 'should let me set an existing value' do
|
31
97
|
route = [['$and', :array], [0, :hash],
|
32
98
|
['#weather', :hash], ['something', :array]]
|
@@ -9,9 +9,13 @@ module Depth::Enumeration
|
|
9
9
|
Class.new do
|
10
10
|
include Depth::Actions
|
11
11
|
include Depth::Enumeration::Enumerable
|
12
|
-
attr_reader :base
|
12
|
+
attr_reader :base, :creation_proc, :next_proc,
|
13
|
+
:key_transformer
|
13
14
|
def initialize(base)
|
14
15
|
@base = base
|
16
|
+
@creation_proc = proc { |o, k, v| o[k] = v }
|
17
|
+
@next_proc = proc { |o, k| o[k] }
|
18
|
+
@key_transformer = proc { |_, k| k }
|
15
19
|
end
|
16
20
|
end
|
17
21
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: depth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|