class JSON::PullParser

Overview

This class allows you to consume JSON on demand, token by token.

Each read_* method consumes the next token. Sometimes it consumes only one token (like #read_begin_array), sometimes it consumes a full valid value (like #read_array).

You must be careful when calling those methods, as they move forward into the JSON input you are pulling. Calling #read_string twice will return the next two strings (if possible), not twice the same.

If you try to read a token which is not the one currently under the cursor location, an exception ParseException will be raised.

Example:

input = %(
  {
    "type": "event",
    "values": [1, 4, "three", 10]
  }
)
pull = JSON::PullParser.new(input)
pull.read_begin_object
pull.read_object_key # => "type"
pull.read_string     # => "event"
# Actually you can also use `read_string` to read a key
pull.read_string # => "values"
pull.read_begin_array
pull.read_int    # => 1
pull.read_int    # => 4
pull.read_string # => "three"
pull.read_int    # => 10
pull.read_end_array
pull.read_end_object

Another example reading the same object:

pull = JSON::PullParser.new(input)
pull.read_object do |key|
  case key
  when "type"
    pull.read_string # => "event"
  when "values"
    pull.read_array do
      if v = pull.read?(Int8)
        v
      else
        pull.read_string
      end
    end
  end
end

This example fails:

pull = JSON::PullParser.new(input)
pull.read_begin_object
pull.read_object_key # => "type"
pull.read_string     # => "event"
pull.read_end_object # => raise an exception. The current token is a string ("values"), not the end of an object.

Defined in:

json/pull_parser.cr

Constructors

Instance Method Summary

Instance methods inherited from class Reference

==(other : self)
==(other : JSON::Any)
==(other : YAML::Any)
==(other)
==
, dup dup, hash(hasher) hash, inspect(io : IO) : Nil inspect, object_id : UInt64 object_id, pretty_print(pp) : Nil pretty_print, same?(other : Reference)
same?(other : Nil)
same?
, to_s(io : IO) : Nil to_s

Constructor methods inherited from class Reference

new new

Instance methods inherited from class Object

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other)
===
, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash
hash
, in?(collection) : Bool
in?(*values : Object) : Bool
in?
, inspect(io : IO) : Nil
inspect : String
inspect
, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO)
to_json
to_json
, to_pretty_json(indent : String = " ")
to_pretty_json(io : IO, indent : String = " ")
to_pretty_json
, to_s(io : IO) : Nil
to_s : String
to_s
, to_yaml(io : IO)
to_yaml
to_yaml
, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

Class methods inherited from class Object

from_json(string_or_io, root : String)
from_json(string_or_io)
from_json
, from_yaml(string_or_io : String | IO) from_yaml

Constructor Detail

def self.new(input) #

Creates a PullParser which will consume the JSON input.

input must be a String or an IO.


[View source]

Instance Method Detail

def bool_value : Bool #

[View source]
def column_number #

Returns the current column number.


[View source]
def float_value : Float64 #

[View source]
def int_value : Int64 #

[View source]
def kind : Kind #

[View source]
def line_number #

Returns the current line number.


[View source]
def location : Tuple(Int32, Int32) #

Returns the current location.

The location is a tuple {line number, column number}.


[View source]
def max_nesting : Int32 #

[View source]
def max_nesting=(max_nesting) #

[View source]
def on_key(key, & : self -> _) #

Reads an object keys and yield when key is found.

All the other object keys are skipped.

Returns the return value of the block or Nil if the key was not read.


[View source]
def on_key!(key, & : self -> _) #

Reads an object keys and yield when key is found. If not found, raise an Exception.

All the other object keys are skipped.

Returns the return value of the block.


[View source]
def raise(message : String) #

Raises ParseException with message at current location.


[View source]
def raw_value : String #

[View source]
def read?(klass : Bool.class) #

Reads a Bool value and returns it.

If the value is not a Bool, returns nil.


[View source]
def read?(klass : Int8.class) #

Reads an Int8 value and returns it.

If the value is not an integer or does not fit in a Int8 variable, it returns nil.


[View source]
def read?(klass : Int16.class) #

Reads an Int16 value and returns it.

If the value is not an integer or does not fit in a Int16 variable, it returns nil.


[View source]
def read?(klass : Int32.class) #

Reads an Int32 value and returns it.

If the value is not an integer or does not fit in a Int32 variable, it returns nil.


[View source]
def read?(klass : Int64.class) #

Reads an Int64 value and returns it.

If the value is not an integer or does not fit in a Int64 variable, it returns nil.


[View source]
def read?(klass : UInt8.class) #

Reads an UInt8 value and returns it.

If the value is not an integer or does not fit in a UInt8 variable, it returns nil.


[View source]
def read?(klass : UInt16.class) #

Reads an UInt16 value and returns it.

If the value is not an integer or does not fit in a UInt16 variable, it returns nil.


[View source]
def read?(klass : UInt32.class) #

Reads an UInt32 value and returns it.

If the value is not an integer or does not fit in a UInt32 variable, it returns nil.


[View source]
def read?(klass : UInt64.class) #

Reads an Int64 value and returns it.

If the value is not an integer or does not fin in an Int64 variable, it returns nil.


[View source]
def read?(klass : Float32.class) #

Reads an Float32 value and returns it.

If the value is not an integer or does not fit in an Float32, it returns nil. If the value was actually an integer, it is converted to a float.


[View source]
def read?(klass : Float64.class) #

Reads an Float64 value and returns it.

If the value is not an integer or does not fit in a Float64 variable, it returns nil. If the value was actually an integer, it is converted to a float.


[View source]
def read?(klass : String.class) #

Reads a String value and returns it.

If the value is not a String, returns nil.


[View source]
def read_array(&) #

Reads a whole array.

It reads the beginning of the array, yield each value of the array, and reads the end of the array. You have to consumes the values, if any, so the pull parser does not fail when reading the end of the array.

If the array is empty, it does not yield.


[View source]
def read_array_or_null(&) #

Reads an array or a null value, and returns it.


[View source]
def read_begin_array #

Reads the beginning of an array.


[View source]
def read_begin_object #

Reads the beginning of an object.


[View source]
def read_bool #

Reads a Bool value.


[View source]
def read_bool_or_null #

Reads a Bool or a null value, and returns it.


[View source]
def read_end_array #

Reads the end of an array.


[View source]
def read_end_object #

Reads the end of an object.


[View source]
def read_float #

Reads a float value.

If the value is actually an integer, it is converted to float.


[View source]
def read_float_or_null #

Reads a float or a null value, and returns it.


[View source]
def read_int #

Reads an integer value.


[View source]
def read_int_or_null #

Reads an integer or a null value, and returns it.


[View source]
def read_next #

Reads the next lexer's token.

Contrary to #read_raw, it does not read a full value. For example if the next token is the beginning of an array, it will stop there, while #read_raw would have read the whole array.


[View source]
def read_null #

Reads a null value and returns it.


[View source]
def read_null_or(&) #

Reads a null value and returns it, or executes the given block if the value is not null.


[View source]
def read_object(&) #

Reads a whole object.

It reads the beginning of the object, yield each key and key location, and reads the end of the object. You have to consumes the values, if any, so the pull parser does not fail when reading the end of the object.

If the object is empty, it does not yield.


[View source]
def read_object_key #

Reads an object's key and returns it.


[View source]
def read_object_or_null(&) #

Reads an object or a null value, and returns it.


[View source]
def read_raw(json) #

Reads the new value and fill the a JSON builder with it.

Use this method with a JSON::Builder to read a JSON while building another one.


[View source]
def read_raw #

Read the next value and returns it.

The value is returned as a json string. If the value is an array or an object, it returns a string representing the full value. If the value in unknown, it raises a ParseException.

pull = JSON::PullParser.new %([null, true, 1, "foo", [1, "two"], {"foo": "bar"}])
pull.read_begin_array
pull.read_raw # => "null"
pull.read_raw # => "true"
pull.read_raw # => "1"
pull.read_raw # => "\"foo\""
pull.read_raw # => "[1,\"two\"]"
pull.read_raw # => "{\"foo\":\"bar\"}"
pull.read_end_array

[View source]
def read_string #

Reads a string and returns it.


[View source]
def read_string_or_null #

Reads a string or a null value, and returns it.


[View source]
def skip #

Skips the next value.

It skips the whole value, not only the next lexer's token. For example if the next value is an array, the whole array will be skipped.


[View source]
def string_value : String #

[View source]