Module: NOSJ

Defined in:
lib/nosj.rb,
lib/nosj/json.rb,
lib/nosj/version.rb,
lib/nosj/multi_json.rb,
sig/nosj.rbs

Overview

Public interfaces only. The native layer (NOSJ.parse_native and friends) and the JSON drop-in's patched JSON singleton methods are implementation detail and deliberately unsigned.

Defined Under Namespace

Modules: JSONDropIn Classes: Error, GeneratorError, MultiJsonAdapter, NestingError

Constant Summary collapse

VERSION =

The gem version.

Returns:

  • (String)
"0.1.0"

Class Method Summary collapse

Class Method Details

.at_pointer(source, pointer, opts = nil) ⇒ Object?

Partial parsing by JSON Pointer (with the standard +~0+/+~1+ escapes). The matched subtree materializes under the same options as parse.

Examples:

NOSJ.at_pointer(json, "/users/3/name")  #=> "grace" or nil

Parameters:

  • source (String)

    the JSON document

  • pointer (String)

    a JSON Pointer (empty string = whole document)

  • opts (Hash, nil) (defaults to: nil)

    materialization options

Returns:

  • (Object, nil)

    the matched value, or nil when the pointer does not resolve

Raises:

  • (ArgumentError)

    for a malformed pointer (non-empty without a leading /)



174
175
176
# File 'lib/nosj.rb', line 174

def self.at_pointer(source, pointer, opts = nil)
  at_pointer_native(source, pointer, opts)
end

.at_pointers(source, pointers, opts = nil) ⇒ Array<Object, nil>

Batch at_pointer: the pointer-string counterpart of dig_many, resolving the whole set in one pass.

Examples:

NOSJ.at_pointers(json, ["/users/3/name", "/meta/count"])
#=> ["grace", 42]

Parameters:

  • source (String)

    the JSON document

  • pointers (Array<String>)

    JSON Pointers, one per result

  • opts (Hash, nil) (defaults to: nil)

    materialization options

Returns:

  • (Array<Object, nil>)

    positionally aligned with pointers

Raises:

  • (ArgumentError)

    for malformed pointers



190
191
192
# File 'lib/nosj.rb', line 190

def self.at_pointers(source, pointers, opts = nil)
  at_pointers_native(source, pointers, opts)
end

.dig(source, *path) ⇒ Object?

Partial parsing, Hash#dig-shaped: extracts one value from a JSON string without materializing the rest of the document. Skipped content is stepped over at SIMD block speed, so a lookup costs what it skips, not what the document weighs.

Examples:

NOSJ.dig(json, "users", 3, "name")  #=> "grace" or nil

Parameters:

  • source (String)

    the JSON document

  • path (Array<String, Symbol, Integer>)

    object keys and array indices; unlike Array#dig, negative indices return nil (JSON Pointer has no equivalent)

Returns:

  • (Object, nil)

    the matched value, or nil when the path does not resolve

Raises:

  • (ArgumentError)

    for path elements that are not Strings, Symbols, or Integers



133
134
135
# File 'lib/nosj.rb', line 133

def self.dig(source, *path)
  dig_native(source, path)
end

.dig_many(source, paths, opts = nil) ⇒ Array<Object, nil>

Batch dig: many paths resolved in ONE pass over the document. The walk descends only into subtrees some path still needs, so a batch costs about as much as its single deepest lookup.

On malformed documents a batch may raise where a single dig would return nil: one pass scans every byte some path needs.

Examples:

NOSJ.dig_many(json, [["users", 3, "name"], ["meta", "count"]])
#=> ["grace", 42]

Parameters:

  • source (String)

    the JSON document

  • paths (Array<Array<String, Symbol, Integer>>)

    one dig path per result

  • opts (Hash, nil) (defaults to: nil)

    materialization options (parse's symbolize_names, freeze, ...)

Returns:

  • (Array<Object, nil>)

    positionally aligned with paths

Raises:

  • (ArgumentError)

    for malformed paths



155
156
157
# File 'lib/nosj.rb', line 155

def self.dig_many(source, paths, opts = nil)
  dig_many_native(source, paths, opts)
end

.generate(obj, opts = nil) ⇒ String

Generates JSON, JSON.generate-compatible: identical output bytes, including the gem's exact float formatting. Implemented natively (no Ruby forwarder frame; the definition lives in the extension).

Examples:

NOSJ.generate({"a" => [1, true]})  #=> '{"a":[1,true]}'

Parameters:

  • obj (Object)

    the value tree to serialize

  • opts (Hash, nil) (defaults to: nil)

    indent, space, space_before, object_nl, array_nl, max_nesting (Integer or false), allow_nan, ascii_only, script_safe (alias escape_slash), strict, depth, buffer_initial_length

Returns:

  • (String)

    the JSON document

Raises:

  • (GeneratorError)

    for non-finite floats without allow_nan, unsupported objects under strict, or broken string encodings

  • (NestingError)

    when nesting exceeds max_nesting



# File 'lib/nosj.rb', line 64

.parse(source, opts = nil) ⇒ Object

Parses a JSON document, JSON.parse-compatible: same values, same option names, same behavior, byte-for-byte.

The json gem's legacy object-deserialization options (+object_class+, array_class, decimal_class, create_additions) are deliberately unsupported and raise ArgumentError.

Examples:

NOSJ.parse('{"a":[1,true]}')                      #=> {"a" => [1, true]}
NOSJ.parse('{"a":1}', symbolize_names: true)      #=> {a: 1}

Parameters:

  • source (String)

    the JSON document (UTF-8 or US-ASCII)

  • opts (Hash, nil) (defaults to: nil)

    symbolize_names, freeze, max_nesting (Integer or false for unlimited), allow_nan, allow_trailing_comma

Returns:

  • (Object)

    the parsed value tree

Raises:

  • (RuntimeError)

    when the document is malformed or not UTF-8

  • (ArgumentError)

    for unsupported options



60
61
62
# File 'lib/nosj.rb', line 60

def self.parse(source, opts = nil)
  parse_native(source, opts)
end

.pretty_generate(obj, opts = nil) ⇒ String

Generates human-readable JSON, JSON.pretty_generate-compatible (two-space indent, newlines between elements). Options override the pretty defaults and are otherwise the same as generate.

Parameters:

  • obj (Object)

    the value tree to serialize

  • opts (Hash, nil) (defaults to: nil)

Returns:

  • (String)

    the pretty-printed JSON document



91
92
93
94
# File 'lib/nosj.rb', line 91

def self.pretty_generate(obj, opts = nil)
  opts = opts.nil? ? PRETTY_GENERATE_OPTS : PRETTY_GENERATE_OPTS.merge(opts)
  generate_native(obj, opts)
end

.valid?(source, opts = nil) ⇒ Boolean

Validates a document without building any Ruby values: the full parser (tokenizers, string decode, number validation) runs into a null sink, 1.8-2.5x faster than parse.

Returns true iff NOSJ.parse(source, opts) would succeed: parse refusals (malformed JSON, wrong encoding, too-deep nesting) are false, while option and argument-type errors still raise exactly like parse.

Examples:

NOSJ.valid?('{"a":1}')  #=> true
NOSJ.valid?('{"a":}')   #=> false

Parameters:

  • source (String)

    the JSON document

  • opts (Hash, nil) (defaults to: nil)

    same options as parse

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)

    for unsupported options



113
114
115
# File 'lib/nosj.rb', line 113

def self.valid?(source, opts = nil)
  valid_native(source, opts)
end