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.

Returns:

  • (Boolean)


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

def requires_header?
  false
end