diff --git a/lib/format_parser.rb b/lib/format_parser.rb index 1a95d76f..b9df9005 100644 --- a/lib/format_parser.rb +++ b/lib/format_parser.rb @@ -5,6 +5,7 @@ # top-level methods of the library. module FormatParser require_relative 'format_parser/version' + require_relative 'hash_utils' require_relative 'attributes_json' require_relative 'image' require_relative 'audio' diff --git a/lib/hash_utils.rb b/lib/hash_utils.rb new file mode 100644 index 00000000..31becc9c --- /dev/null +++ b/lib/hash_utils.rb @@ -0,0 +1,19 @@ +# based on https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/keys.rb#L116 +# I chose to copy this method instead of adding activesupport as a dependency +# because we want to have the least number of dependencies +module FormatParser + class HashUtils + def self.deep_transform_keys(object, &block) + case object + when Hash + object.each_with_object({}) do |(key, value), result| + result[yield(key)] = deep_transform_keys(value, &block) + end + when Array + object.map { |e| deep_transform_keys(e, &block) } + else + object + end + end + end +end diff --git a/spec/hash_utils_spec.rb b/spec/hash_utils_spec.rb new file mode 100644 index 00000000..4643584f --- /dev/null +++ b/spec/hash_utils_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +describe FormatParser::HashUtils do + describe '.deep_transform_keys' do + it 'transforms all the keys in a hash' do + hash = { aa: 1, 'bb' => 2 } + result = described_class.deep_transform_keys(hash, &:to_s) + + expect(result).to eq('aa' => 1, 'bb' => 2) + end + + it 'transforms all the keys in a array of hashes' do + array = [{ aa: 1, bb: 2 }, { cc: 3, dd: [{c: 2, d: 3}] }] + result = described_class.deep_transform_keys(array, &:to_s) + + expect(result).to eq( + [{'aa' => 1, 'bb' => 2}, {'cc' => 3, 'dd' => [{'c' => 2, 'd' => 3}]}] + ) + end + + it 'transforms all the keys in a hash recursively' do + hash = { aa: 1, bb: { cc: 22, dd: 3 } } + result = described_class.deep_transform_keys(hash, &:to_s) + + expect(result).to eq('aa' => 1, 'bb' => { 'cc' => 22, 'dd' => 3}) + end + + it 'does nothing for an non array/hash object' do + object = Object.new + result = described_class.deep_transform_keys(object, &:to_s) + + expect(result).to eq(object) + end + end +end