Class: IOStreams::Tabular::Parser::Fixed

Inherits:
Base
  • Object
show all
Defined in:
lib/io_streams/tabular/parser/fixed.rb

Overview

Parsing and rendering fixed length data

Defined Under Namespace

Classes: Column, Layout

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(layout:, truncate: true) ⇒ Fixed

Returns [IOStreams::Tabular::Parser]

Parameters:

layout: [Array<Hash>]
  [
    {size: 23, key: "name"},
    {size: 40, key: "address"},
    {size:  2},
    {size:  5, key: "zip"},
    {size:  8, key: "age", type: :integer},
    {size: 10, key: "weight", type: :float, decimals: 2}
  ]

Notes:

  • Leave out the name of the key to ignore that column during parsing, and to space fill when rendering. For example as a filler.

Types:

:string
  This is the default type.
  Applies space padding and the value is left justified.
  Returns value as a String
:integer
  Applies zero padding to the left.
  Returns value as an Integer
  Raises Errors::ValueTooLong when the supplied value cannot be rendered in `size` characters.
:float
  Applies zero padding to the left.
  Returns value as a float.
  The :size is the total size of this field including the `.` and the decimals.
  Number of :decimals
  Raises Errors::ValueTooLong when the supplied value cannot be rendered in `size` characters.

In some circumstances the length of the last column is variable.

layout: [Array<Hash>]
  [
    {size: 23, key: "name"},
    {size: :remainder, key: "rest"}
  ]

By setting a size of :remainder it will take the rest of the line as the value for that column.

A size of :remainder and no :key will discard the remainder of the line without validating the length.

layout: [Array<Hash>]
  [
    {size: 23, key: "name"},
    {size: :remainder}
  ]


56
57
58
59
# File 'lib/io_streams/tabular/parser/fixed.rb', line 56

def initialize(layout:, truncate: true)
  @layout   = Layout.new(layout)
  @truncate = truncate
end

Instance Attribute Details

#layoutObject (readonly)

Returns the value of attribute layout.



6
7
8
# File 'lib/io_streams/tabular/parser/fixed.rb', line 6

def layout
  @layout
end

#truncateObject (readonly)

Returns the value of attribute truncate.



6
7
8
# File 'lib/io_streams/tabular/parser/fixed.rb', line 6

def truncate
  @truncate
end

Instance Method Details

#line_lengthObject

The required line length for every fixed length line



62
63
64
# File 'lib/io_streams/tabular/parser/fixed.rb', line 62

def line_length
  layout.length
end

#parse(line) ⇒ Object

Returns [Hash<Symbol, String>] fixed layout values extracted from the supplied line. String will be encoded to encoding



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/io_streams/tabular/parser/fixed.rb', line 83

def parse(line)
  unless line.is_a?(String)
    raise(Errors::TypeMismatch, "Line must be a String when format is :fixed. Actual: #{line.class.name}")
  end

  if layout.length.positive? && (line.length != layout.length)
    raise(Errors::InvalidLineLength, "Expected line length: #{layout.length}, actual line length: #{line.length}")
  end

  hash  = {}
  index = 0
  layout.columns.each do |column|
    if column.size == -1
      hash[column.key] = column.parse(line[index..-1]) if column.key
      break
    end

    # Ignore "columns" that have no keys. E.g. Fillers
    hash[column.key] = column.parse(line[index, column.size]) if column.key
    index += column.size
  end
  hash
end

#render(row, header) ⇒ Object

Returns [String] fixed layout values extracted from the supplied hash.

Notes:

  • A nil value is considered an empty string

  • When a supplied value exceeds the column size it is truncated.



71
72
73
74
75
76
77
78
79
# File 'lib/io_streams/tabular/parser/fixed.rb', line 71

def render(row, header)
  hash = header.to_hash(row)

  result = ""
  layout.columns.each do |column|
    result << column.render(hash[column.key], truncate)
  end
  result
end

#requires_header?Boolean

The header is required as an argument and cannot be supplied in the file itself.



108
109
110
# File 'lib/io_streams/tabular/parser/fixed.rb', line 108

def requires_header?
  false
end