lib/stupidedi/config/interchange_config.rb
# frozen_string_literal: true
module Stupidedi
using Refinements
class Config
#
# The interchange control segments (ISA/ISE) are versioned independently
# from the functional group segments (GS/GE). Because different interchange
# versions can have unique grammars, this table serves as an indirection.
#
# Opinion: The interchange version is encoded within the ISA segment, whose
# definition is recursively dependent on the interchange version. Worse yet,
# the version is encoded as the fourteenth element (in versions 00501 and
# 00401), instead of say, the 1st element.
#
# This seems to indicate the versioning was an afterthought. The same
# thought process was applied when versioning the functional group segments,
# which has the version encoded in GS08.
#
# The best we can do to cope with this is to presume the ISA and GS segments
# have an underlying grammar that won't change between versions. We do this
# by parsing 12 things following "ISA", using the 12th thing as the version
# number, and then starting over at "ISA" and parsing with actual grammar.
# Then the grammar can specify which elements specify delimiters and all the
# other parts of the interchange header, like the TA1 segment.
#
# @see http://x12.org/rfis/ "Relations Between the ISA and GS Segments.PDF"
#
class InterchangeConfig
include Inspect
# @return [Hash<String, InterchangeDef>]
attr_reader :table
def_delegators :@table, :defined_at?
def initialize
@table = Hash.new
end
def customize(&block)
tap(&block)
end
#
# @example
# table = InterchangeConfig.new
#
# table.register("00602") { SixOhTwo::InterchangeDef }
# table.register("00501") { FiveOhOne::InterchangeDef }
# table.register("00401") { FourOhOne::InterchangeDef }
# table.register("00304") { ThreeOhFour::InterchangeDef }
#
# @return [void]
def register(version, definition = nil, &constructor)
if block_given?
@table[version] = constructor
else
@table[version] = definition
end
end
# @return [InterchangeDef]
def at(version)
x = @table[version]
x.is_a?(Proc) ? x.call : x
end
# @return [void]
def pretty_print(q)
q.text "InterchangeConfig"
q.group(2, "(", ")") do
q.breakable ""
@table.keys.each do |e|
unless q.current_group.first?
q.text ","
q.breakable
end
q.pp e
end
end
end
end
end
end