Description

fixed_layout_mapper is a library that maps to RubyObject from fixed-length data.

Sample

require 'pp'
require 'fixed-layout-mapper'

mapper = FixedLayoutMapper::Mapper.define_layout do
  layout :sub_layout do
    col :sub_f1, 1
    col :sub_f2, 2
  end

  col :f1, 5 
  col :f2, :sub_layout
  col :f3, [2] * 3
  col :f4, [1, 2, :sub_layout]
  col :f5, 3 do |v|
    v * 2
  end
end

data = %w(12345 a bb 00 11 22 a bb c dd 123)
pp mapper.map(data.join)
#=> #<struct 
#    f1="12345",
#    f2=#<struct  sub_f1="a", sub_f2="bb">,
#    f3=["00", "11", "22"],
#    f4=["a", "bb", #<struct  sub_f1="c", sub_f2="dd">],
#    f5="123123">

Detail

Define columns

Layout definition is started in "define_layout" method.

mapper = FixedLayoutMapper::Mapper.define_layout do
  definitions...
end

Columns are defined by "col" method.

col symbol, record_def

record_def is

  • numeric: define column which cut the string with its width.

    #ex)
    mapper = FixedLayoutMapper::Mapper.define_layout do
      col :f, 3
    end
    
    p mapper.map("0123")
    #=> #<struct f="012">
    
  • array: define array column with use its each contents.

    #ex)
    mapper = FixedLayoutMapper::Mapper.define_layout do
      col :f1, [1, 2]
      col :f2, [1] * 3
    end
    
    p mapper.map("001123")
    #=> #<struct f1=["0", "01"], f2=["1", "2", "3"]>
    
  • sub_layout_key: define column which use its layout.
    see Sub layout.

Sub layout

if you want to name to layout, you can use "layout" method.
A field defined by "col" method called outside the block of "layout" method is implicitly defined in the default layout.

layout layout_name(symbol) do
    column definitions...
end

When sub layout is defined, you can use its layout in other layout definition.

mapper = FixedLayoutMapper::Mapper.define_layout do
  layout :sub1 do
    col :sub_f1, 1
    col :sub_f2, 2
  end
  col :f1, 1
  col :f2, :sub1
end

p mapper.map("0123")
#=> #<struct f1="0", f2=#<struct sub_f1="1", sub_f2="23">>

You can also use sub layout in array def.

mapper = FixedLayoutMapper::Mapper.define_layout do
  layout :sub1 do
    col :sub_f1, 1
    col :sub_f2, 2
  end
  col :f1, [1, :sub1]
end

p mapper.map("0123")
#=> #<struct f1=["0", #<struct sub_f1="1", sub_f2="23"]>

you can use sub layout in map method.
if symbol is passed to the second argument in map method, use its layout.

mapper = FixedLayoutMapper::Mapper.define_layout do
  layout :sub1 do
    col :sub_f1, 1
    col :sub_f2, 2
  end
  col :f1, [1, :sub1]
end

p mapper.map("0123")
#=> #<struct f1=["0", #<struct sub_f1="1", sub_f2="23"]>
p mapper.map("0123", :sub1)
#=> #<struct sub_f1="0", sub_f2="12">

Conversion

If "col" method is given block, the raw value is passed to the block and the field value becomes the return value of the block.

mapper = FixedLayoutMapper::Mapper.define_layout do
  col :f1, 3 do |v|
    v + "_" + v
  end
  col :f2, 3, &:upcase
end

p mapper.map("012abc")
#=> #<struct f1="012_012", f2="ABC">