Class: AceMQ::AMQP::TOMLCodec::Reader Private

Inherits:
Object
  • Object
show all
Defined in:
lib/acemq/amqp/codec/toml/reader.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Turns TOML text into a Hash.

A recursive-descent reader over StringScanner, covering TOML 1.0: bare, quoted and dotted keys; basic, literal and multi-line strings; integers in four bases; floats including inf and nan; booleans; all four date and time kinds; arrays; inline tables; tables; and arrays of tables.

The four date and time kinds, and what Ruby has for them

TOML distinguishes an instant from a wall-clock reading, and Ruby has types for only some of that:

  • An offset date-time names an instant, and becomes a Time carrying the offset the sender wrote.
  • A local date-time deliberately has no offset — it is a reading on somebody's wall — and Ruby has no unzoned time. It becomes a Time in the reading process's own zone, which is the closest honest answer and is worth knowing before two of them are compared across machines.
  • A local date becomes a Date.
  • A local time — 10:32:00, with no date at all — has no Ruby type whatsoever, so it comes back as the String the sender wrote rather than as a Time on a day nobody mentioned.

Defined Under Namespace

Classes: Invalid

Constant Summary collapse

BARE_KEY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

/[A-Za-z0-9_-]+/
BLANKS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

/(?:[ \t\r\n]|#[^\n]*)+/
INLINE_SPACE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

/[ \t]*/
ESCAPES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

{
  "b" => "\b", "t" => "\t", "n" => "\n", "f" => "\f", "r" => "\r",
  '"' => '"', "\\" => "\\"
}.freeze
INFINITY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

->(text) { text.start_with?("-") ? -Float::INFINITY : Float::INFINITY }
INSTANT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

->(text) { Time.iso8601(text.sub(/[Tt ]/, "T").sub(/z\z/, "Z")) }
ATOMS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Ordered, because a date starts with digits and would otherwise be read as an integer, and 1.5 would be read as the integer 1.

[
  [/true(?![\w-])/, ->(_) { true }],
  [/false(?![\w-])/, ->(_) { false }],
  [/\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:[Zz]|[+-]\d{2}:\d{2})/,
   INSTANT],
  [/\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}:\d{2}(?:\.\d+)?/, ->(text) { Time.parse(text) }],
  [/\d{4}-\d{2}-\d{2}(?![\d:])/, ->(text) { Date.iso8601(text) }],
  [/\d{2}:\d{2}:\d{2}(?:\.\d+)?/, ->(text) { text }],
  [/[+-]?inf(?![\w-])/, INFINITY],
  [/[+-]?nan(?![\w-])/, ->(_) { Float::NAN }],
  [/[+-]?\d[\d_]*(?:\.\d[\d_]*)?[eE][+-]?\d[\d_]*/, lambda { |text|
    Float(text.delete("_"))
  }],
  [/[+-]?\d[\d_]*\.\d[\d_]*/, ->(text) { Float(text.delete("_")) }],
  [/0x\h[\h_]*/, ->(text) { Integer(text.delete("_"), 16) }],
  [/0o[0-7][0-7_]*/, ->(text) { Integer(text.delete("_").delete_prefix("0o"), 8) }],
  [/0b[01][01_]*/, ->(text) { Integer(text.delete("_").delete_prefix("0b"), 2) }],
  [/[+-]?\d[\d_]*(?![\w.-])/, ->(text) { Integer(text.delete("_"), 10) }]
].freeze

Instance Method Summary collapse

Constructor Details

#initialize(source) ⇒ Reader

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Reader.



90
91
92
93
94
# File 'lib/acemq/amqp/codec/toml/reader.rb', line 90

def initialize(source)
  @scanner = StringScanner.new(source)
  @root = {}
  @table = @root
end

Instance Method Details

#parse ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Hash)

Raises:



98
99
100
101
102
103
104
105
106
107
# File 'lib/acemq/amqp/codec/toml/reader.rb', line 98

def parse
  loop do
    @scanner.skip(BLANKS)
    break if @scanner.eos?

    statement
    end_of_line!
  end
  @root
end