Class: Aspera::DotContainer
- Inherits:
-
Object
- Object
- Aspera::DotContainer
- Defined in:
- lib/aspera/dot_container.rb
Overview
Convert dotted-path to/from nested Hash/Array container
Class Method Summary collapse
-
.dotted_to_container(path, value, result = nil) ⇒ Hash, Array
Insert extended value
valueinto structresultatpath.
Instance Method Summary collapse
-
#initialize(container) ⇒ DotContainer
constructor
A new instance of DotContainer.
-
#to_dotted ⇒ Hash
Convert nested Hash/Array container to dotted-path Hash.
Constructor Details
#initialize(container) ⇒ DotContainer
Returns a new instance of DotContainer.
51 52 53 54 55 56 |
# File 'lib/aspera/dot_container.rb', line 51 def initialize(container) Aspera.assert_type(container, Hash) # tail (pop,push) contains the next element to display # elements are [path, value] @stack = container.empty? ? [] : [[[], container]] end |
Class Method Details
.dotted_to_container(path, value, result = nil) ⇒ Hash, Array
Insert extended value value into struct result at path
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/aspera/dot_container.rb', line 14 def dotted_to_container(path, value, result = nil) # Typed keys keys = path.split(OPTION_DOTTED_SEPARATOR).map{ |k| int_or_string(k)} # Create, or re-use first level container current = (result ||= new_hash_or_array_from_key(keys.first)) # walk the path, and create sub-containers if necessary keys.each_cons(2) do |k, next_k| array_requires_integer_index!(current, k) current = (current[k] ||= new_hash_or_array_from_key(next_k)) end # Assign value at last index array_requires_integer_index!(current, keys.last) current[keys.last] = value result end |
Instance Method Details
#to_dotted ⇒ Hash
Convert nested Hash/Array container to dotted-path Hash
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/aspera/dot_container.rb', line 60 def to_dotted result = {} until @stack.empty? path, current = @stack.pop to_insert = nil # empty things are left intact if current.respond_to?(:empty?) && current.empty? to_insert = current else case current when Hash add_elements(path, current) when Array # Array has no nested structures -> list of Strings if current.none?{ |i| i.is_a?(Array) || i.is_a?(Hash)} to_insert = current.map(&:to_s) # Array of Hashes with only 'name' keys -> list of Strings elsif current.all?{ |i| i.is_a?(Hash) && i.keys == ['name']} to_insert = current.map{ |i| i['name']} # Array of Hashes with only 'name' and 'value' keys -> Hash of key/values elsif current.all?{ |i| i.is_a?(Hash) && i.keys.sort == %w[name value]} add_elements(path, current.each_with_object({}){ |i, h| h[i['name']] = i['value']}) else add_elements(path, current.each_with_index.map{ |v, i| [i, v]}) end else to_insert = current end end result[path.map(&:to_s).join(OPTION_DOTTED_SEPARATOR)] = to_insert unless to_insert.nil? end result end |