Module: Lutaml::Json::GeneratorOptions

Defined in:
lib/lutaml/json/generator_options.rb

Overview

Filters the options LutaML threads through serialization down to the subset the JSON generator accepts.

json 2.x silently ignored unknown generator options; json 3.0 raises ArgumentError on them, so LutaML's own options (:register, :pretty and any caller-supplied extras) have to be stripped before they reach JSON.generate.

Constant Summary collapse

BASE_PERMITTED =

Options the generator accepts on both json 2.x and 3.x. Measured against 2.9.1, 2.15.2, 2.19.9, 2.20.0, 2.21.1, 2.21.2 and 3.0.0. :escape_slash is NOT here because json 3.0 removed it; on 2.x it still arrives via DERIVED_PERMITTED. :allow_duplicate_key IS here because the generator accepts it on every version while JSON::State never exposed it as an accessor, so the derived half alone would miss it.

i[
  allow_duplicate_key allow_nan array_nl as_json ascii_only
  buffer_initial_length depth indent max_nesting object_nl script_safe
  sort_keys space space_before strict
].freeze
DERIVED_PERMITTED =

Additive, so a json release that adds an option needs no change here. Opal's JSON shim has no State class, hence the guard.

if defined?(::JSON::State)
  accessors = ::JSON::State.instance_methods(false).grep(/\A[a-z_][a-z0-9_]*=\z/)
  accessors.map { |name| name.to_s.chomp("=").to_sym }
else
  []
end.freeze
PERMITTED =
(BASE_PERMITTED | DERIVED_PERMITTED).freeze
RENAMED =

json 3.0 removed :escape_slash, which was only ever an alias of :script_safe. Dropping it would silently stop escaping slashes, so it is translated instead of discarded.

{ escape_slash: :script_safe }.freeze

Class Method Summary collapse

Class Method Details

.filter(options) ⇒ Object



44
45
46
47
48
49
50
51
# File 'lib/lutaml/json/generator_options.rb', line 44

def self.filter(options)
  return {} unless options.is_a?(::Hash)

  options.each_with_object({}) do |(key, value), kept|
    key = RENAMED.fetch(key, key) unless PERMITTED.include?(key)
    kept[key] = value if PERMITTED.include?(key)
  end
end

.lutaml_options?(argument) ⇒ Boolean

Ruby's JSON generator calls #to_json with a JSON::State whenever a document is nested inside another JSON.generate call. That is the generator's own state, not a LutaML options hash, and json 3.0 removed JSON::State#[], so it must never be read like one.



57
58
59
# File 'lib/lutaml/json/generator_options.rb', line 57

def self.lutaml_options?(argument)
  argument.nil? || argument.is_a?(::Hash)
end