class CSVPP::Parser

Attributes

col_sep[R]
format[R]

Public Class Methods

new(format:, col_sep: DEFAULT_COL_SEP, convert_type: true) click to toggle source
# File lib/csvpp/parser.rb, line 43
def initialize(format:, col_sep: DEFAULT_COL_SEP, convert_type: true)
  @format = format
  @col_sep = format.col_sep || col_sep
  @convert_type = convert_type
end
parse(input:, format:, col_sep: DEFAULT_COL_SEP, convert_type: true, &block) click to toggle source

@param input [String] path to input file @param format [Format] @param col_sep [String]

@return [Array<Object>]

# File lib/csvpp/parser.rb, line 12
def self.parse(input:,
               format:,
               col_sep: DEFAULT_COL_SEP,
               convert_type: true,
               &block)

  new(
    format: format,
    col_sep: col_sep,
    convert_type: convert_type
  ).parse(input, &block)
end
parse_str(input:, format:, col_sep: DEFAULT_COL_SEP, convert_type: true, &block) click to toggle source

@param input [String] input string @param format [Format] @param col_sep [String]

@return [Array<Object>]

# File lib/csvpp/parser.rb, line 30
def self.parse_str(input:,
                   format:,
                   col_sep: DEFAULT_COL_SEP,
                   convert_type: true,
                   &block)

  new(
    format: format,
    col_sep: col_sep,
    convert_type: convert_type
  ).parse_str(input, &block)
end

Public Instance Methods

multiline?() click to toggle source
# File lib/csvpp/parser.rb, line 57
def multiline?
  format.multiline?
end
parse(path, &block) click to toggle source
# File lib/csvpp/parser.rb, line 49
def parse(path, &block)
  parse_io(File.open(path), &block)
end
parse_str(str, &block) click to toggle source
# File lib/csvpp/parser.rb, line 53
def parse_str(str, &block)
  parse_io(str, &block)
end

Private Instance Methods

add_result!(results, hash) { |hash| ... } click to toggle source
# File lib/csvpp/parser.rb, line 79
def add_result!(results, hash)
  results << if block_given? && (obj = yield(hash))
               obj
             else
               hash
             end
end
each_line_with_index(io) { |line, index| ... } click to toggle source

Yield each line and corresponding index of io to given block, but skipping the first lines according to the skip parameter defined in format.

# File lib/csvpp/parser.rb, line 152
def each_line_with_index(io)
  offset = format.skip
  io.each_line.with_index do |line, index|
    yield(line, index) unless index < offset
  end
end
multiline_start?(line_id) click to toggle source
# File lib/csvpp/parser.rb, line 146
def multiline_start?(line_id)
  format.multiline_start?(line_id)
end
parse_io(io, &block) click to toggle source
# File lib/csvpp/parser.rb, line 87
def parse_io(io, &block)
  return parse_multiline(io, &block) if multiline?

  results = []

  each_line_with_index(io) do |line, index|
    line_number = index + 1
    columns = line.split(col_sep, -1)

    hash = {}
    format.var_names.each do |var|
      hash['line_number'] = line_number

      index = format.index(var)
      value = columns[index]

      set_value!(hash, var, value)
    end

    add_result!(results, hash, &block)
  end

  results
end
parse_multiline(io, &block) click to toggle source
# File lib/csvpp/parser.rb, line 112
def parse_multiline(io, &block)
  results = []
  hash = nil

  each_line_with_index(io) do |line, index|
    line_number = index + 1
    columns = line.split(col_sep, -1)
    line_id = columns[0]

    # If we reach a start of a group...
    if multiline_start?(line_id)
      # ...yield the previous group...
      add_result!(results, hash, &block) if hash

      # ...and start building a new one.
      hash = {}
      hash['line_number'] = line_number
    end

    next if hash.nil?

    format.vars_for_line(line_id).each do |var|
      index = format.index(var)
      value = columns[index]
      set_value!(hash, var, value)
    end
  end

  # Yield the last group.
  add_result!(results, hash, &block) if hash

  results
end
set_value!(hash, var, value) click to toggle source
# File lib/csvpp/parser.rb, line 63
def set_value!(hash, var, value)
  hash[var] = value
  return unless @convert_type

  type = format.type(var)
  return if type.nil?

  hash[var] = convert(
    value,
    to: type,
    missings: format.missings(var),
    true_values: format.true_values(var),
    false_values: format.false_values(var)
  )
end