module DeepHashStruct
Mixin module for converter.
Constants
- VERSION
Public Instance Methods
deep_struct(input)
click to toggle source
Converts a Hash to a Struct. If the Hash has nested Hash objects, they are converted to Struct as well.
output = deep_struct({x: 1, y: {z: 2}}) output.x #=> 1 output.y.z #=> 2
@param [Hash] input @return [Struct]
# File lib/deep_hash_struct.rb, line 13 def deep_struct(input) output = input.clone levels = expand_levels(output) collapse_levels(levels) klass = Struct.new(*output.keys, keyword_init: true) klass.new(output) end
Private Instance Methods
collapse_levels(levels)
click to toggle source
# File lib/deep_hash_struct.rb, line 46 def collapse_levels(levels) levels.reverse_each do |k, context| if context[k].is_a?(Hash) klass = Struct.new(*context[k].keys, keyword_init: true) context[k] = klass.new(context[k]) end end end
deep_struct_enumerable(enumerable)
click to toggle source
@param [Enumerable] enumerable
# File lib/deep_hash_struct.rb, line 41 def deep_struct_enumerable(enumerable) enumerable.map { |v| v.is_a?(Hash) ? deep_struct(v) : v } end
expand_levels(output)
click to toggle source
# File lib/deep_hash_struct.rb, line 21 def expand_levels(output) levels = output.keys.map { |key| [key, output] } levels.each do |key, context| if context[key].is_a?(Hash) # overwrite the shared reference with input by a new reference context[key] = context[key].clone subset = context[key] subset.each do |subkey, subvalue| levels.push([subkey, subset]) if subvalue.is_a?(Hash) subset[subkey] = deep_struct_enumerable(subset[subkey]) if subvalue.is_a?(Array) end elsif context[key].is_a?(Array) context[key] = deep_struct_enumerable(context[key]) end end levels end