diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-09-23 00:06:29 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-09-23 00:06:29 +0000 |
commit | 98dbb0a488d7b0093f352938210d9578b0f7a8a6 (patch) | |
tree | 25654204f8de2672556a696199fa209b8f8ff1b3 /lib/gitlab/utils | |
parent | 9ce26d3dfdf4194f32c470cd3102b4376a53ef2f (diff) | |
download | gitlab-ce-98dbb0a488d7b0093f352938210d9578b0f7a8a6.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/utils')
-rw-r--r-- | lib/gitlab/utils/inline_hash.rb | 54 | ||||
-rw-r--r-- | lib/gitlab/utils/safe_inline_hash.rb | 30 |
2 files changed, 84 insertions, 0 deletions
diff --git a/lib/gitlab/utils/inline_hash.rb b/lib/gitlab/utils/inline_hash.rb new file mode 100644 index 00000000000..5985e4da845 --- /dev/null +++ b/lib/gitlab/utils/inline_hash.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module Gitlab + module Utils + module InlineHash + extend self + + # Transforms a Hash into an inline Hash by merging its nested keys. + # + # Input + # + # { + # 'root_param' => 'Root', + # nested_param: { + # key: 'Value' + # }, + # 'very' => { + # 'deep' => { + # 'nested' => { + # 'param' => 'Deep nested value' + # } + # } + # } + # } + # + # + # Result + # + # { + # 'root_param' => 'Root', + # 'nested_param.key' => 'Value', + # 'very.deep.nested.param' => 'Deep nested value' + # } + # + def merge_keys(hash, prefix: nil, connector: '.') + result = {} + base_prefix = prefix ? "#{prefix}#{connector}" : '' + pairs = hash.map { |key, value| ["#{base_prefix}#{key}", value] } + + until pairs.empty? + key, value = pairs.shift + + if value.is_a?(Hash) + value.each { |k, v| pairs.unshift ["#{key}#{connector}#{k}", v] } + else + result[key] = value + end + end + + result + end + end + end +end diff --git a/lib/gitlab/utils/safe_inline_hash.rb b/lib/gitlab/utils/safe_inline_hash.rb new file mode 100644 index 00000000000..644d87c6876 --- /dev/null +++ b/lib/gitlab/utils/safe_inline_hash.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Gitlab + module Utils + class SafeInlineHash + # Validates the hash size using `Gitlab::Utils::DeepSize` before merging keys using `Gitlab::Utils::InlineHash` + def initialize(hash, prefix: nil, connector: '.') + @hash = hash + end + + def self.merge_keys!(hash, prefix: nil, connector: '.') + new(hash).merge_keys!(prefix: prefix, connector: connector) + end + + def merge_keys!(prefix:, connector:) + raise ArgumentError, 'The Hash is too big' unless valid? + + Gitlab::Utils::InlineHash.merge_keys(hash, prefix: prefix, connector: connector) + end + + private + + attr_reader :hash + + def valid? + Gitlab::Utils::DeepSize.new(hash).valid? + end + end + end +end |