summaryrefslogtreecommitdiff
path: root/lib/gitlab/utils
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-09-23 00:06:29 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-09-23 00:06:29 +0000
commit98dbb0a488d7b0093f352938210d9578b0f7a8a6 (patch)
tree25654204f8de2672556a696199fa209b8f8ff1b3 /lib/gitlab/utils
parent9ce26d3dfdf4194f32c470cd3102b4376a53ef2f (diff)
downloadgitlab-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.rb54
-rw-r--r--lib/gitlab/utils/safe_inline_hash.rb30
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