Class: Webhookdb::Json::Encoder

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

Overview

Based on ActiveSupport::JSON::Encoding::JSONGemEncoder. Removes the HTML escaping code (which is slow), but otherwise continues to depend on the as_json approach.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = nil) ⇒ Encoder

Returns a new instance of Encoder.



33
34
35
# File 'lib/webhookdb/json.rb', line 33

def initialize(options=nil)
  @options = options || DEFAULT_OPTIONS
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



31
32
33
# File 'lib/webhookdb/json.rb', line 31

def options
  @options
end

Instance Method Details

#encode(value) ⇒ Object



37
38
39
# File 'lib/webhookdb/json.rb', line 37

def encode(value)
  return stringify(jsonify(value.as_json(@options.dup)))
end

#jsonify(value) ⇒ Object

Convert an object into a “JSON-ready” representation composed of primitives like Hash, Array, String, Numeric, and true/false/nil. Recursively calls #as_json to the object to recursively build a fully JSON-ready object.

This allows developers to implement #as_json without having to worry about what base types of objects they are allowed to return or having to remember to call #as_json recursively.

Note: the options hash passed to object.to_json is only passed to object.as_json, not any of this method’s recursive #as_json calls.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/webhookdb/json.rb', line 54

def jsonify(value)
  case value
    when Rational
      value.to_s
    when String, Numeric, NilClass, TrueClass, FalseClass
      value.as_json
    when Hash
      result = {}
      value.each do |k, v|
        result[jsonify(k)] = jsonify(v)
      end
      result
    when Array
      value.map { |v| jsonify(v) }
    else
      jsonify value.as_json
  end
end

#stringify(jsonified) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/webhookdb/json.rb', line 73

def stringify(jsonified)
  # If this breaks because we actually need to handle more types,
  # add them to jsonify, like Rational.
  #
  # We can't use `mode: :rails` here since we can't control
  # whether to use html-escaping (we don't want to use it) without using `Oj.optimize_rails`,
  # which causes other problems- we want to use ISO8601 encoding with millsecond precision,
  # but we get JSON-gem-style formatting (even if setting flags to modify ActiveSupport params)
  # when we use `optimize-rails` (but not mode: :rails, since we stringify the time beforehand).
  return ::Oj.dump(jsonified, mode: :strict, **@options)
end