darthjee-core_ext 1.7.4 → 3.0.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.
Files changed (101) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +63 -9
  3. data/.gitignore +2 -0
  4. data/.reek.yml +3 -0
  5. data/.rubocop.yml +18 -1
  6. data/.rubocop_todo.yml +15 -8
  7. data/ARRAY_README.md +72 -15
  8. data/CLASS_README.md +154 -0
  9. data/DATE_README.md +19 -9
  10. data/Dockerfile +18 -5
  11. data/ENUMERABLE_README.md +154 -4
  12. data/Gemfile +13 -0
  13. data/HASH_README.md +276 -135
  14. data/MATH_README.md +14 -10
  15. data/Makefile +7 -0
  16. data/OBJECT_README.md +18 -35
  17. data/README.md +12 -4
  18. data/Rakefile +1 -0
  19. data/SYMBOL_README.md +13 -18
  20. data/config/check_specs.yml +20 -0
  21. data/config/rubycritc.rb +12 -0
  22. data/config/yardstick.yml +45 -3
  23. data/core_ext.gemspec +10 -18
  24. data/docker-compose.yml +24 -7
  25. data/lib/darthjee/core_ext/array/hash_builder.rb +22 -5
  26. data/lib/darthjee/core_ext/array.rb +22 -14
  27. data/lib/darthjee/core_ext/class.rb +29 -10
  28. data/lib/darthjee/core_ext/date.rb +1 -0
  29. data/lib/darthjee/core_ext/enumerable.rb +67 -29
  30. data/lib/darthjee/core_ext/hash/cameliazable.rb +52 -21
  31. data/lib/darthjee/core_ext/hash/chain_fetcher.rb +18 -1
  32. data/lib/darthjee/core_ext/hash/changeable.rb +88 -0
  33. data/lib/darthjee/core_ext/hash/deep_hash_constructor/setter.rb +112 -0
  34. data/lib/darthjee/core_ext/hash/deep_hash_constructor.rb +127 -62
  35. data/lib/darthjee/core_ext/hash/key_changeable.rb +138 -66
  36. data/lib/darthjee/core_ext/hash/key_changer.rb +146 -45
  37. data/lib/darthjee/core_ext/hash/keys_sorter.rb +43 -6
  38. data/lib/darthjee/core_ext/hash/squasher.rb +131 -18
  39. data/lib/darthjee/core_ext/hash/transformable.rb +133 -41
  40. data/lib/darthjee/core_ext/hash/transposeable.rb +37 -8
  41. data/lib/darthjee/core_ext/hash/value_changer.rb +76 -36
  42. data/lib/darthjee/core_ext/hash.rb +6 -4
  43. data/lib/darthjee/core_ext/math.rb +37 -6
  44. data/lib/darthjee/core_ext/numeric.rb +13 -2
  45. data/lib/darthjee/core_ext/object.rb +27 -0
  46. data/lib/darthjee/core_ext/symbol.rb +22 -2
  47. data/lib/darthjee/core_ext/version.rb +1 -1
  48. data/scripts/check_readme.sh +6 -0
  49. data/scripts/rubycritic.sh +10 -0
  50. data/spec/integration/readme/array_spec.rb +96 -0
  51. data/spec/integration/readme/class_spec.rb +123 -0
  52. data/spec/integration/readme/date_spec.rb +20 -0
  53. data/spec/integration/readme/enumerable_spec.rb +87 -0
  54. data/spec/integration/readme/hash_spec.rb +400 -0
  55. data/spec/integration/readme/math_spec.rb +31 -0
  56. data/spec/integration/readme/object_spec.rb +49 -0
  57. data/spec/integration/readme/symbol_spec.rb +29 -0
  58. data/spec/integration/yard/darthjee/core_ext/array_spec.rb +1 -1
  59. data/spec/integration/yard/darthjee/core_ext/class/default_value_spec.rb +10 -8
  60. data/spec/integration/yard/darthjee/core_ext/enumerable_spec.rb +24 -4
  61. data/spec/integration/yard/darthjee/core_ext/hash/cameliazable_spec.rb +11 -0
  62. data/spec/integration/yard/darthjee/core_ext/hash/changeable_spec.rb +68 -0
  63. data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +34 -0
  64. data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +65 -0
  65. data/spec/integration/yard/darthjee/core_ext/hash/key_changeable_spec.rb +8 -0
  66. data/spec/integration/yard/darthjee/core_ext/hash/key_changer_spec.rb +59 -0
  67. data/spec/integration/yard/darthjee/core_ext/hash/keys_sorter_spec.rb +25 -0
  68. data/spec/integration/yard/darthjee/core_ext/hash/squasher_spec.rb +60 -0
  69. data/spec/integration/yard/darthjee/core_ext/hash/transformable_spec.rb +67 -37
  70. data/spec/integration/yard/darthjee/core_ext/hash/transposeable_spec.rb +35 -0
  71. data/spec/integration/yard/darthjee/core_ext/hash/value_changer_spec.rb +1 -1
  72. data/spec/integration/yard/darthjee/core_ext/hash_spec.rb +13 -2
  73. data/spec/integration/yard/darthjee/core_ext/math_spec.rb +28 -0
  74. data/spec/integration/yard/darthjee/core_ext/numeric_spec.rb +11 -0
  75. data/spec/integration/yard/darthjee/core_ext/object_spec.rb +47 -0
  76. data/spec/integration/yard/darthjee/core_ext/symbol_spec.rb +17 -0
  77. data/spec/lib/array_spec.rb +2 -1
  78. data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +64 -0
  79. data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +16 -156
  80. data/spec/lib/darthjee/core_ext/hash/keys_sorter_spec.rb +5 -4
  81. data/spec/lib/darthjee/core_ext/hash/squasher_spec.rb +8 -2
  82. data/spec/lib/darthjee/core_ext/hash/value_changer_spec.rb +5 -13
  83. data/spec/lib/hash_spec.rb +87 -147
  84. data/spec/lib/object_spec.rb +32 -0
  85. data/spec/lib/symbol_spec.rb +2 -2
  86. data/spec/spec_helper.rb +4 -2
  87. data/spec/support/models/client.rb +23 -0
  88. data/spec/support/models/dummy_iterator.rb +4 -4
  89. data/spec/support/models/hash/value_changer/dummy.rb +1 -0
  90. data/spec/support/shared_examples/array/array_random.rb +2 -3
  91. data/spec/support/shared_examples/hash/chain_hash_keys_changer.rb +1 -1
  92. data/spec/support/shared_examples/hash/deep_hash.rb +166 -0
  93. data/spec/support/shared_examples/hash/hash_keys_changer.rb +3 -3
  94. data/spec/support/shared_examples/hash/hash_squasher.rb +54 -9
  95. data/spec/support/shared_examples/hash/keys_sorter.rb +266 -6
  96. data/spec/support/shared_examples/hash/map_to_hash.rb +1 -1
  97. data/spec/support/shared_examples/hash/remap.rb +4 -4
  98. data/spec/support/shared_examples/hash/value_changer.rb +2 -2
  99. metadata +41 -189
  100. data/lib/darthjee/core_ext/hash/to_hash_mapper.rb +0 -25
  101. data/spec/lib/darthjee/core_ext/hash/to_hash_mapper_spec.rb +0 -11
@@ -3,17 +3,16 @@
3
3
  module Darthjee
4
4
  module CoreExt
5
5
  module Hash
6
- # Module holding methods responsible for camelizing
7
- # keys of a hash
6
+ # Module holding methods for camelizing keys of a hash
8
7
  #
9
8
  # @api public
10
9
  module Cameliazable
11
- # Change keys to CamelCase without changing the
12
- # original hash
10
+ # Change keys to CamelCase without changing the original hash
13
11
  #
14
12
  # @return [::Hash] new hash with changed keys
15
13
  # @param [::Hash] options options of camelization
16
- # @option options [::Boolean] uppercase_first_letter: flag
14
+ # @option options [::TrueClass,::FalseClass]
15
+ # uppercase_first_letter: flag
17
16
  # defining the type of CamelCase
18
17
  #
19
18
  # @see Hash::KeyChanger#camelize_keys
@@ -28,28 +27,28 @@ module Darthjee
28
27
  # @example
29
28
  # hash = { first_key: 1, 'second_key' => 2 }
30
29
  # options = { uppercase_first_letter: false }
31
- # hash.camelize_keys(options) # returns {
30
+ # hash.camelize_keys(**options) # returns {
32
31
  # # firstKey: 1,
33
32
  # # 'secondKey' => 2
34
33
  # # }
35
34
  #
36
- def camelize_keys(options = {})
37
- dup.camelize_keys!(options)
35
+ def camelize_keys(**)
36
+ dup.camelize_keys!(**)
38
37
  end
39
38
 
40
- # Change keys to CamelCase changing the
41
- # original hash
39
+ # Change keys to CamelCase changing the original hash
42
40
  #
43
41
  # @return [::Hash] new hash with changed keys
44
42
  # @param [::Hash] options options of camelization
45
- # @option options [::Boolean] uppercase_first_letter: flag
43
+ # @option options [::TrueClass,::FalseClass]
44
+ # uppercase_first_letter: flag
46
45
  # defining the type of CamelCase
47
46
  #
48
47
  # @example (see #camelize_keys)
49
48
  #
50
49
  # @see #camelize_keys
51
- def camelize_keys!(options = {})
52
- Hash::KeyChanger.new(self).camelize_keys(options)
50
+ def camelize_keys!(**)
51
+ Hash::KeyChanger.new(self).camelize_keys(**)
53
52
  end
54
53
 
55
54
  # Camelize all keys in the hash as `key.camelize(:lower)
@@ -63,8 +62,8 @@ module Darthjee
63
62
  # # 'secondKey' => 2
64
63
  # # }
65
64
  #
66
- def lower_camelize_keys(options = {})
67
- dup.lower_camelize_keys!(options)
65
+ def lower_camelize_keys(**)
66
+ dup.lower_camelize_keys!(**)
68
67
  end
69
68
 
70
69
  # Camelize all keys in the hash
@@ -72,18 +71,50 @@ module Darthjee
72
71
  # @return [::Hash] self after changing the keys
73
72
  #
74
73
  # @example (see #lower_camelize_keys)
75
- def lower_camelize_keys!(options = {})
74
+ def lower_camelize_keys!(**options)
76
75
  options = options.merge(uppercase_first_letter: false)
77
76
 
78
- camelize_keys!(options)
77
+ camelize_keys!(**options)
79
78
  end
80
79
 
81
- def underscore_keys(options = {})
82
- dup.underscore_keys!(options)
80
+ # Change all keys to be snakecase
81
+ #
82
+ # THis method does not change the original hash
83
+ #
84
+ # @param options [::Hash]
85
+ # @option options recursive [::TrueClass,::FalseClass]
86
+ # flag for recursive transformation
87
+ #
88
+ # @see Hash::KeyChanger#change_keys
89
+ #
90
+ # @example underscoring all keys
91
+ # hash = { firstKey: 1, 'SecondKey' => 2 }
92
+ #
93
+ # hash.underscore_keys # returns {
94
+ # # first_key: 1,
95
+ # # 'second_key' => 2
96
+ # # }
97
+ #
98
+ # @return [::Hash]
99
+ def underscore_keys(**)
100
+ dup.underscore_keys!(**)
83
101
  end
84
102
 
85
- def underscore_keys!(options = {})
86
- Hash::KeyChanger.new(self).underscore_keys(options)
103
+ # Change all keys to be snakecase
104
+ #
105
+ # THis method changes the original hash
106
+ #
107
+ # @param options [::Hash]
108
+ # @option options recursive [::TrueClass,::FalseClass]
109
+ # flag for recursive transformation
110
+ #
111
+ # @see Hash::KeyChanger#change_keys
112
+ #
113
+ # @example (see #underscore_keys)
114
+ #
115
+ # @return [::Hash]
116
+ def underscore_keys!(**)
117
+ Hash::KeyChanger.new(self).underscore_keys(**)
87
118
  end
88
119
  end
89
120
  end
@@ -7,6 +7,8 @@ module Darthjee
7
7
  #
8
8
  # @api private
9
9
  #
10
+ # @author Darthjee
11
+ #
10
12
  # @see Darthjee::CoreExt::Hash#chain_fetch
11
13
  class ChainFetcher
12
14
  def initialize(hash, *keys, &block)
@@ -21,13 +23,23 @@ module Darthjee
21
23
  #
22
24
  # @return [Object] value fetched from array
23
25
  def fetch
24
- block.present? ? fetch_with_block : fetch_without_block
26
+ return fetch_with_block if block.present?
27
+
28
+ fetch_without_block
25
29
  end
26
30
 
27
31
  private
28
32
 
33
+ # @private
29
34
  attr_reader :hash, :keys, :block
30
35
 
36
+ # @private
37
+ #
38
+ # Perform chain fetch when block is given
39
+ #
40
+ # The block will be called in case a key is missed
41
+ #
42
+ # @return [Object]
31
43
  def fetch_with_block
32
44
  @hash = hash.fetch(keys.shift) do |*args|
33
45
  missed_keys = keys
@@ -37,6 +49,11 @@ module Darthjee
37
49
  hash
38
50
  end
39
51
 
52
+ # @private
53
+ #
54
+ # Perform chain fetch when block is not given
55
+ #
56
+ # @return [Object]
40
57
  def fetch_without_block
41
58
  @hash = hash.fetch(keys.shift) until keys.empty?
42
59
  hash
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Darthjee
4
+ module CoreExt
5
+ module Hash
6
+ # Methods responsible for changing hash values
7
+ #
8
+ # @api public
9
+ #
10
+ # @author Darthjee
11
+ module Changeable
12
+ # Creates a new hash with changes in its values
13
+ #
14
+ # @param options [::Hash]
15
+ # @option options [::TrueClass,::FalseClass]
16
+ # recursive (true) flag indicating recursive sorting
17
+ # @option options [::TrueClass,::FalseClass]
18
+ # skip_inner (true) Flag indicating to skip running
19
+ # transformation on Hash objects
20
+ #
21
+ # @yield (value) changing value block
22
+ #
23
+ # @return [::Hash]
24
+ #
25
+ # @example Simple Usage
26
+ # hash = { a: 1, b: 2 }
27
+ # hash.change_values do |value|
28
+ # value + 1
29
+ # end # returns { a: 2, b: 3 }
30
+ #
31
+ # @example Skipping inner hash transformation
32
+ # hash = { a: 1, b: { c: 1 } }
33
+ #
34
+ # hash.change_values(&:to_s)) # returns {
35
+ # # a: "1",
36
+ # # b: { c: "1" }
37
+ # # }
38
+ #
39
+ # @example Not skipping inner hash transformation
40
+ # hash = { a: 1, b: { c: 1 } }
41
+ #
42
+ # hash.change_values(skip_inner: false, &:to_s))
43
+ # # returns {
44
+ # # a: "1",
45
+ # # b: "{:c=>1}"
46
+ # # }
47
+ def change_values(**, &)
48
+ deep_dup.change_values!(**, &)
49
+ end
50
+
51
+ # Changes the values of a hash
52
+ #
53
+ # @param options [::Hash]
54
+ # @option options [::TrueClass,::FalseClass]
55
+ # recursive (true) flag indicating recursive sorting
56
+ # @option options [::TrueClass,::FalseClass]
57
+ # skip_inner (true) Flag indicating to skip running
58
+ # transformation on Hash objects
59
+ #
60
+ # @yield (value) changing value block
61
+ #
62
+ # @return [::Hash]
63
+ #
64
+ # @example (see change_values)
65
+ #
66
+ # @example Changing inner hash
67
+ # inner_hash = { c: 2 }
68
+ # hash = { a: 1, b: inner_hash }
69
+ #
70
+ # hash.change_values!(&:to_s)
71
+ #
72
+ # inner_hash # changed to { c: "2" }
73
+ #
74
+ # @example Not changing inner hash
75
+ # inner_hash = { c: 2 }
76
+ # hash = { a: 1, b: inner_hash }
77
+ #
78
+ # hash.change_values!(skip_inner: false, &:to_s)
79
+ #
80
+ # hash # changed to { a: "1", b: "{:c=>2}" }
81
+ # inner_hash # still { c: 2 }
82
+ def change_values!(**, &)
83
+ Hash::ValueChanger.new(**, &).change(self)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Darthjee
4
+ module CoreExt
5
+ module Hash
6
+ class DeepHashConstructor
7
+ # @api private
8
+ #
9
+ # Class responsible for setting value localized inside hash
10
+ #
11
+ # @example Simple usage
12
+ # hash = {}
13
+ # base = 'person'
14
+ # setter = Darthjee::CoreExt::Hash::DeepHashConstructor::Setter.new(
15
+ # hash, base
16
+ # )
17
+ #
18
+ # setter.set('age', 21)
19
+ #
20
+ # hash # changed to {
21
+ # # 'person' => {
22
+ # # 'age' => 21,
23
+ # # }
24
+ # # }
25
+ class Setter
26
+ # @param hash [Hash] hash to be changed
27
+ # @param base_key [::String] base key of hash where
28
+ # subhash will be created
29
+ def initialize(hash, base_key)
30
+ @hash = hash
31
+ @base_key = base_key
32
+ end
33
+
34
+ # Sets a value in the correct key inside the hash
35
+ #
36
+ # @param key [::String,::NilClass] key where value will live
37
+ # @param value [::Object] value to be set
38
+ #
39
+ # @return [::Object] value
40
+ #
41
+ # @example (see DeepHashConstructor)
42
+ #
43
+ # @example With Array index
44
+ # hash = {}
45
+ # base = 'person[0]'
46
+ # setter = Darthjee::CoreExt::Hash::DeepHashConstructor::Setter.new(
47
+ # hash, base
48
+ # )
49
+ #
50
+ # setter.set('age', 21)
51
+ #
52
+ # hash # changed to {
53
+ # # 'person' => [{
54
+ # # 'age' => 21,
55
+ # # }]
56
+ # # }
57
+ def set(key, value)
58
+ return hash[base_key] = value unless key || index
59
+ return array[index] = value unless key
60
+
61
+ sub_hash[key] = value
62
+ end
63
+
64
+ private
65
+
66
+ # @private
67
+ attr_reader :hash, :base_key
68
+
69
+ # @private
70
+ # Extract index of array from base_key
71
+ #
72
+ # @return [::NilClass,::Integer]
73
+ def index
74
+ return @index if instance_variable_defined?('@index')
75
+
76
+ match = base_key.match(/\[([^)]+)\]/)
77
+ return @index = nil unless match
78
+
79
+ @index = match[1].to_i
80
+ end
81
+
82
+ # @private
83
+ # Returns array that will receive value
84
+ #
85
+ # This array is only created / used when base_key
86
+ # contains index
87
+ #
88
+ # @return [::Array]
89
+ def array
90
+ return @array if instance_variable_defined?('@array')
91
+
92
+ key_without_index = base_key.tr("[#{index}]", '')
93
+
94
+ @array = hash[key_without_index] ||= []
95
+ end
96
+
97
+ # @private
98
+ # Returns sub hash that will receive the value
99
+ #
100
+ # This sub_hash is only build when key is not nil
101
+ #
102
+ # @return [::Hash]
103
+ def sub_hash
104
+ return array[index] ||= {} if index
105
+
106
+ hash[base_key] ||= {}
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -3,90 +3,155 @@
3
3
  module Darthjee
4
4
  module CoreExt
5
5
  module Hash
6
+ # @api private
7
+ #
8
+ # @author Darthjee
9
+ #
10
+ # Class responsible for creating a Hash deep hash
11
+ #
12
+ # Deep hash construction happens when a hash of one layer
13
+ # (no sub hashes) has keys that, once explitted, can be
14
+ # assembled in a hash with many layers
15
+ #
16
+ # @see Transformable#squash
17
+ # @see Transformable#to_deep_hash
18
+ #
19
+ # @example (see Transformable#to_deep_hash)
20
+ # @example General Usage
21
+ # hash = {
22
+ # 'account.person.name[0]' => 'John',
23
+ # 'account.person.name[1]' => 'Wick',
24
+ # 'account.person.age' => 20,
25
+ # 'account.number' => '102030',
26
+ # :'house.number' => 67,
27
+ # :'house.zip' => 12_345
28
+ # }
29
+ #
30
+ # constructor = Darthjee::CoreExt::Hash::DeepHashConstructor.new('.')
31
+ #
32
+ # constructor.deep_hash(hash) # returns {
33
+ # # 'account' => {
34
+ # # 'person' => {
35
+ # # 'name' => ['John', 'Wick'],
36
+ # # 'age' => 20
37
+ # # },
38
+ # # 'number' => '102030',
39
+ # # },
40
+ # # 'house' => {
41
+ # # 'number' => 67,
42
+ # # 'zip' => 12345
43
+ # # }
44
+ # # }
6
45
  class DeepHashConstructor
7
- attr_accessor :separator
46
+ autoload :Setter, "#{PATH}/hash/deep_hash_constructor/setter"
8
47
 
9
- def initialize(separator)
48
+ # @param separator [::String] keys splitter
49
+ def initialize(separator = '.')
10
50
  @separator = separator
11
51
  end
12
52
 
13
- def deep_hash(object)
14
- if object.is_a? Array
15
- array_deep_hash(object)
16
- elsif object.is_a? Hash
17
- hash_deep_hash(object)
18
- else
19
- object
53
+ # Performs deep hash transformation
54
+ #
55
+ # @param hash [::Hash] On layered hash
56
+ #
57
+ # @return [::Hash] Many layered hash
58
+ #
59
+ # @example (see DeepHashConstructor)
60
+ def deep_hash(hash)
61
+ break_keys(hash).tap do
62
+ hash.keys.each do |key|
63
+ hash[key] = deep_hash_value(hash[key])
64
+ end
20
65
  end
21
66
  end
22
67
 
23
68
  private
24
69
 
25
- def array_deep_hash(array)
26
- array.map do |value|
27
- value.is_a?(Hash) ? deep_hash(value) : value
28
- end
29
- end
30
-
31
- def hash_deep_hash(hash)
32
- {}.tap do |new_hash|
33
- hash.each do |k, v|
34
- base_key, child_key = split_key(k, separator)
35
- set_deep_hash_positioned_value(new_hash, base_key, v, child_key)
36
- end
70
+ # @private
71
+ attr_reader :separator
37
72
 
38
- new_hash.each do |k, v|
39
- new_hash[k] = deep_hash(v)
40
- end
73
+ # @private
74
+ # break the keys creating sub-hashes
75
+ #
76
+ # @param hash [::Hash] hash to be broken
77
+ #
78
+ # @example Breaking many level keys
79
+ # hash = {
80
+ # 'account.person.name[0]' => 'John',
81
+ # 'account.person.name[1]' => 'Wick',
82
+ # 'account.person.age' => 20,
83
+ # 'account.number' => '102030',
84
+ # :'house.number' => 67,
85
+ # :'house.zip' => 12_345
86
+ # }
87
+ #
88
+ # constructor = Darthjee::CoreExt::Hash::DeepHashConstructor.new('.')
89
+ #
90
+ # constructor.send(:break_keys, hash)
91
+ #
92
+ # # Returns {
93
+ # # 'account' => {
94
+ # # %w[person name[0]] => 'John',
95
+ # # %w[person name[1]] => 'Wick',
96
+ # # %w[person age] => 20,
97
+ # # %w[number] => '102030'
98
+ # # },
99
+ # # 'house' => {
100
+ # # %w[number] => 67,
101
+ # # %w[zip] => 12_345
102
+ # # }
103
+ # # }
104
+ #
105
+ # @return [Hash]
106
+ def break_keys(hash)
107
+ hash.keys.each do |key|
108
+ value = hash.delete(key)
109
+ base_key, child_key = split_key(key, separator)
110
+ Setter.new(hash, base_key).set(child_key, value)
41
111
  end
42
- end
43
112
 
44
- def split_key(key, separator)
45
- separator_rxp = separator == '.' ? "\\#{separator}" : separator
46
- skipper = "[^#{separator}]"
47
- regexp = Regexp.new("^(#{skipper}*)#{separator_rxp}(.*)")
48
- match = key.match(regexp)
49
-
50
- match ? match[1..2] : key
113
+ hash
51
114
  end
52
115
 
53
- def set_deep_hash_array_value(hash, base_key, index, value, key = nil)
54
- key_without_index = base_key.gsub("[#{index}]", '')
55
- hash[key_without_index] ||= []
116
+ # @private
117
+ #
118
+ # Recursively proccess a value calling deep hash on it
119
+ #
120
+ # @return [::Object]
121
+ def deep_hash_value(object)
122
+ return array_deep_hash(object) if object.is_a? Array
123
+ return deep_hash(object) if object.is_a? Hash
56
124
 
57
- if key.nil?
58
- hash[key_without_index][index] = value
59
- else
60
- hash[key_without_index][index] ||= {}
61
- hash[key_without_index][index][key] = value
62
- end
125
+ object
63
126
  end
64
127
 
65
- def set_deep_hash_positioned_value(new_hash, base_key, value, child_key)
66
- index = array_index(base_key)
67
-
68
- if index
69
- set_deep_hash_array_value(
70
- new_hash, base_key, index,
71
- value, child_key
72
- )
73
- else
74
- set_deep_hash_value(new_hash, base_key, value, child_key)
128
+ # @private
129
+ #
130
+ # Map array performing deep hash on its Hash elements
131
+ #
132
+ # @param array [::Array] array to be mapped
133
+ #
134
+ # @return [::Array]
135
+ def array_deep_hash(array)
136
+ array.map do |value|
137
+ deep_hash_value(value)
75
138
  end
76
139
  end
77
140
 
78
- def array_index(key)
79
- match = key.match(/\[([^)]+)\]/)
80
- match && match[1].to_i
81
- end
141
+ # @private
142
+ #
143
+ # Split key into array of keys
144
+ #
145
+ # @param key [::String,::Symbol] key to be splitted
146
+ # @param separator [::String] string of key splitting
147
+ #
148
+ # @return [::Array<::String>,::String]
149
+ def split_key(key, separator)
150
+ keys = key.is_a?(Array) ? key : key.to_s.split(separator)
82
151
 
83
- def set_deep_hash_value(hash, base_key, value, key = nil)
84
- if key.nil?
85
- hash[base_key] = value
86
- else
87
- hash[base_key] ||= {}
88
- hash[base_key][key] = value
89
- end
152
+ return keys unless keys.second
153
+
154
+ [keys.shift, keys]
90
155
  end
91
156
  end
92
157
  end