Class: ActiveSupport::JSON::Encoding::JSONGemCoderEncoder

Inherits:
Object
  • Object
show all
Defined in:
lib/active_support/json/encoding.rb

Overview

:nodoc:

Constant Summary collapse

JSON_NATIVE_TYPES =
[Hash, Array, Float, String, Symbol, Integer, NilClass, TrueClass, FalseClass, ::JSON::Fragment].freeze
CODER =
::JSON::Coder.new do |value, is_key|
  # Serialize non-String/Symbol keys via #to_s based on the key's own type,
  # mirroring the legacy `jsonify` encoder. (#as_json is intentionally not
  # consulted here: Time#as_json returns an ISO8601 String, yet the key must
  # still be emitted via #to_s for backward compatibility.)
  if is_key
    # Keep compatibility by calling to_s on non-String keys
    if Symbol === value
      next value # Symbol#to_s needlessly allocate a string.
    else
      next value.to_s
    end
  end

  json_value = value.as_json

  # Handle objects returning self from as_json
  if json_value.equal?(value)
    next ::JSON::Fragment.new(::JSON.generate(json_value))
  end
  # Handle objects not returning JSON-native types from as_json
  count = 5
  until JSON_NATIVE_TYPES.include?(json_value.class)
    raise SystemStackError if count == 0
    json_value = json_value.as_json
    count -= 1
  end
  json_value
end

Instance Method Summary collapse

Constructor Details

#initialize(options = nil) ⇒ JSONGemCoderEncoder

Returns a new instance of JSONGemCoderEncoder.



183
184
185
186
187
188
189
190
191
192
# File 'lib/active_support/json/encoding.rb', line 183

def initialize(options = nil)
  if options
    options = options.dup
    @escape = options.delete(:escape) { true }
    @options = options.freeze
  else
    @escape = true
    @options = {}.freeze
  end
end

Instance Method Details

#encode(value) ⇒ Object

Encode the given object into a JSON string



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/active_support/json/encoding.rb', line 195

def encode(value)
  value = value.as_json(@options) unless @options.empty?

  json = CODER.dump(value)

  return json unless @escape

  json.force_encoding(::Encoding::BINARY)
  if @options.fetch(:escape_html_entities, Encoding.escape_html_entities_in_json)
    if Encoding.escape_js_separators_in_json
      json.gsub!(FULL_ESCAPE_REGEX, ESCAPED_CHARS)
    else
      json.gsub!(HTML_ENTITIES_REGEX, ESCAPED_CHARS)
    end
  elsif Encoding.escape_js_separators_in_json
    json.gsub!(JS_SEPARATORS_REGEX, ESCAPED_CHARS)
  end
  json.force_encoding(::Encoding::UTF_8)
end