diff options
Diffstat (limited to 'lib/gitlab/json.rb')
-rw-r--r-- | lib/gitlab/json.rb | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/gitlab/json.rb b/lib/gitlab/json.rb index 8565f664cd4..b51c0a33457 100644 --- a/lib/gitlab/json.rb +++ b/lib/gitlab/json.rb @@ -186,9 +186,14 @@ module Gitlab # The `env` param is ignored because it's not needed in either our formatter or Grape's, # but it is passed through for consistency. # + # If explicitly supplied with a `PrecompiledJson` instance it will skip conversion + # and return it directly. This is mostly used in caching. + # # @param object [Object] # @return [String] def self.call(object, env = nil) + return object.to_s if object.is_a?(PrecompiledJson) + if Feature.enabled?(:grape_gitlab_json, default_enabled: true) Gitlab::Json.dump(object) else @@ -197,6 +202,34 @@ module Gitlab end end + # Wrapper class used to skip JSON dumping on Grape endpoints. + + class PrecompiledJson + UnsupportedFormatError = Class.new(StandardError) + + # @overload PrecompiledJson.new("foo") + # @param value [String] + # + # @overload PrecompiledJson.new(["foo", "bar"]) + # @param value [Array<String>] + def initialize(value) + @value = value + end + + # Convert the value to a String. This will invoke + # `#to_s` on the members of the value if it's an array. + # + # @return [String] + # @raise [NoMethodError] if the objects in an array doesn't support to_s + # @raise [PrecompiledJson::UnsupportedFormatError] if the value is neither a String or Array + def to_s + return @value if @value.is_a?(String) + return "[#{@value.join(',')}]" if @value.is_a?(Array) + + raise UnsupportedFormatError + end + end + class LimitedEncoder LimitExceeded = Class.new(StandardError) |