Module: NOSJ::JSONDropIn

Defined in:
lib/nosj/json.rb

Overview

Implementation detail of require "nosj/json".

Constant Summary collapse

PARSE_OPTS =

quirks_mode rides the fast path because NOSJ.parse is always quirks-mode (top-level scalars parse) and ignores the key; Rails 7.x passes it from ActiveSupport::JSON.decode.

%i[symbolize_names freeze max_nesting allow_nan
allow_trailing_comma quirks_mode].freeze
GENERATE_OPTS =
%i[indent space space_before object_nl array_nl
max_nesting allow_nan ascii_only script_safe
escape_slash strict depth
buffer_initial_length].freeze

Class Method Summary collapse

Class Method Details

.generate(obj, opts, pretty) ⇒ Object



82
83
84
85
86
87
88
# File 'lib/nosj/json.rb', line 82

def generate(obj, opts, pretty)
  pretty ? NOSJ.pretty_generate(obj, opts) : NOSJ.generate(obj, opts)
rescue NOSJ::NestingError => e
  raise ::JSON::NestingError, e.message
rescue NOSJ::GeneratorError => e
  raise ::JSON::GeneratorError, e.message
end

.parse(source, opts) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/nosj/json.rb', line 55

def parse(source, opts)
  # NOSJ.parse is deliberately strict about encodings (json-3.0
  # semantics), but the drop-in must match the installed gem, which
  # accepts more. BINARY strings holding valid UTF-8 are the big
  # real-world case: Rack delivers request bodies as BINARY, so
  # Rails JSON params come through here. Retagging a dup is cheap
  # (copy-on-write bytes), and the validity scan is memoized
  # coderange the parse would compute anyway. Anything else
  # non-UTF-8 (UTF-16, ...) belongs to gem json, which transcodes.
  if source.is_a?(String)
    case source.encoding
    when Encoding::UTF_8, Encoding::US_ASCII
    # the fast path as-is
    when Encoding::BINARY
      utf8 = source.dup.force_encoding(Encoding::UTF_8)
      source = utf8 if utf8.valid_encoding?
    else
      return ::JSON.nosj_original_parse(source, **(opts || {}))
    end
  end
  NOSJ.parse(source, opts)
rescue NOSJ::NestingError => e
  raise ::JSON::NestingError, e.message
rescue NOSJ::ParserError => e
  raise ::JSON::ParserError, e.message
end

.supported?(opts, allowed) ⇒ Boolean

The fast path handles nil or a plain Hash whose every key NOSJ implements; anything else (JSON::State, exotic options, string keys) belongs to gem json.

Returns:

  • (Boolean)


48
49
50
51
52
53
# File 'lib/nosj/json.rb', line 48

def supported?(opts, allowed)
  return true if opts.nil?
  return false unless opts.instance_of?(Hash)
  opts.each_key { |k| return false unless allowed.include?(k) }
  true
end