Class: CSVPlusPlus::Runtime::Position

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/csv_plus_plus/runtime/position.rb

Overview

Keeps track of the position in a file where the parser is. The parser makes various passes over the input but it always needs to track the same things (line number, cell/row index, current cell)

rubocop:disable Metrics/ClassLength

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input) ⇒ Position

Returns a new instance of Position.

Parameters:

  • input (String)


31
32
33
# File 'lib/csv_plus_plus/runtime/position.rb', line 31

def initialize(input)
  rewrite_input!(::CSVPlusPlus::Lexer.preprocess(input))
end

Instance Attribute Details

#cellCell

The current cell index. This will only be set when processing the CSV section

Returns:



14
15
16
# File 'lib/csv_plus_plus/runtime/position.rb', line 14

def cell
  @cell
end

#cell_indexInteger

The current CSV cell index.

This will only be set when processing the CSV section and will throw an exception otherwise. It is up to the caller (the compiler) to make sure it’s called in the context of a compilation stage and/or a #map_row/#map_rows/#map_lines

Returns:

  • (Integer)


14
15
16
# File 'lib/csv_plus_plus/runtime/position.rb', line 14

def cell_index
  @cell_index
end

#line_numberInteger

The current line number being processed. The line number is based on the entire file, irregardless of if it’s parsing the code section or the CSV section

This will only be set when processing the csvpp file and will throw an exception otherwise. It is up to the caller (the compiler) to make sure it’s called in the context of a compilation stage and/or a #map_row/#map_rows/#map_lines

Returns:

  • (Integer)


14
15
16
# File 'lib/csv_plus_plus/runtime/position.rb', line 14

def line_number
  @line_number
end

#row_indexInteger

The current CSV row index. This will only be set when processing the CSV section

This will only be set when processing the CSV section and will throw an exception otherwise. It is up to the caller (the compiler) to make sure it’s called in the context of a compilation stage and/or a #map_row/#map_rows/#map_lines

Returns:

  • (Integer)


14
15
16
# File 'lib/csv_plus_plus/runtime/position.rb', line 14

def row_index
  @row_index
end

Instance Method Details

#cleanup!Object

Clean up the Tempfile we’re using for parsing



86
87
88
89
# File 'lib/csv_plus_plus/runtime/position.rb', line 86

def cleanup!
  input&.close
  input&.unlink
end

#input::Tempfile

The currently available input for parsing. The tmp state will be re-written between parsing the code section and the CSV section

Returns:

  • (::Tempfile)


96
97
98
# File 'lib/csv_plus_plus/runtime/position.rb', line 96

def input
  @input ||= ::T.let(::Tempfile.new, ::T.nilable(::Tempfile))
end

#map_all_cells(rows, &block) ⇒ Array<Array>

Map over all rows and over all of their cells, calling the &block with each Cell

rubocop:disable Naming/BlockForwarding

Parameters:

  • rows (Array<Row>)

Returns:

  • (Array<Array>)


174
175
176
177
# File 'lib/csv_plus_plus/runtime/position.rb', line 174

def map_all_cells(rows, &block)
  self.row_index = 0
  map_lines(rows) { |row| map_row(row.cells, &block) }
end

#map_lines(lines, &block) ⇒ Array

Map over a csvpp file and keep track of line_number and row_index

Parameters:

  • lines (Array)

Returns:

  • (Array)


111
112
113
114
115
116
117
118
# File 'lib/csv_plus_plus/runtime/position.rb', line 111

def map_lines(lines, &block)
  self.line_number = 1
  lines.map do |line|
    ret = block.call(line)
    next_line!
    ret
  end
end

#map_row(row, &block) ⇒ Array

Map over a single row and keep track of the cell and it’s index

Parameters:

  • row (Array<Cell>)

    The row to map each cell over

Returns:

  • (Array)


136
137
138
139
140
141
142
# File 'lib/csv_plus_plus/runtime/position.rb', line 136

def map_row(row, &block)
  row.map.with_index do |cell, index|
    self.cell_index = index
    self.cell = cell if cell.is_a?(::CSVPlusPlus::Cell)
    block.call(cell, index)
  end
end

#map_rows(rows, &block) ⇒ Array

Map over all rows and keep track of row and line numbers

Parameters:

  • rows (Array<Row>)

    The rows to map over (and keep track of indexes)

Returns:

  • (Array)


155
156
157
158
159
160
# File 'lib/csv_plus_plus/runtime/position.rb', line 155

def map_rows(rows, &block)
  self.row_index = 0
  map_lines(rows) do |row|
    block.call(row)
  end
end

#rewrite_input!(data) ⇒ Object

We mutate the input over and over. It’s ok because it’s just a Tempfile

Parameters:

  • data (::String)

    The data to rewrite our input file to



204
205
206
207
208
# File 'lib/csv_plus_plus/runtime/position.rb', line 204

def rewrite_input!(data)
  input&.truncate(0)
  input&.write(data)
  input&.rewind
end

#rownumInteger?

Return the current spreadsheet row number. It parallels @row_index but starts at 1.

Returns:

  • (Integer, nil)


184
185
186
# File 'lib/csv_plus_plus/runtime/position.rb', line 184

def rownum
  row_index + 1
end

#start!(&block) ⇒ Object

Each time we run a parse on the input, reset the runtime state starting at the beginning of the file



192
193
194
195
196
197
198
# File 'lib/csv_plus_plus/runtime/position.rb', line 192

def start!(&block)
  @row_index = @cell_index = 0

  ret = block.call
  finish!
  ret
end