Class: Nacha::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/nacha/parser.rb

Overview

Nacha Parser - deal with figuring out what record type a line is

Constant Summary collapse

DEFAULT_RECORD_TYPES =
[
  'Nacha::Record::FileHeader',
  'Nacha::Record::AdvFileHeader',
  'Nacha::Record::Filler'
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeParser

Returns a new instance of Parser.



17
18
19
# File 'lib/nacha/parser.rb', line 17

def initialize
  @context = Nacha::ParserContext.new
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



15
16
17
# File 'lib/nacha/parser.rb', line 15

def context
  @context
end

Instance Method Details

#add_child(parent, child) ⇒ Object



74
75
76
77
78
79
# File 'lib/nacha/parser.rb', line 74

def add_child(parent, child)
  return unless parent && child

  parent.children << child
  child.parent = parent
end

#detect_possible_record_types(line) ⇒ Object



27
28
29
30
31
# File 'lib/nacha/parser.rb', line 27

def detect_possible_record_types(line)
  Nacha.ach_record_types.filter_map do |record_type|
    record_type if record_type.matcher.match?(line)
  end
end

#parse_all_by_types(line, record_types) ⇒ Object



88
89
90
91
92
93
# File 'lib/nacha/parser.rb', line 88

def parse_all_by_types(line, record_types)
  record_types.filter_map do |rt|
    record_type = rt.is_a?(Class) ? rt : Object.const_get(rt)
    record_type.parse(line) if record_type.matcher.match?(line)
  end
end

#parse_file(file) ⇒ Object



21
22
23
24
25
# File 'lib/nacha/parser.rb', line 21

def parse_file(file)
  @context.parser_started_at = Time.now.utc
  @context.file_name = file
  parse_string(file.read)
end

#parse_first_by_types(line, record_types) ⇒ Object



81
82
83
84
85
86
# File 'lib/nacha/parser.rb', line 81

def parse_first_by_types(line, record_types)
  record_types.lazy.filter_map do |rt|
    record_type = rt.is_a?(Class) ? rt : Object.const_get(rt)
    record_type.parse(line) if record_type.matcher.match?(line)
  end.first
end

#parse_string(str) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/nacha/parser.rb', line 33

def parse_string(str)
  line_num = -1
  records = []
  @context.parser_started_at ||= Time.now.utc
  str.scan(/(.{0,94})[\r\n]*/).each do |line|
    line = line.compact.first.strip
    next if line.empty? || line.start_with?('#') # Skip empty lines and comments

    line_num += 1
    @context.line_number = line_num
    @context.line_length = line.length
    records << process(line, line_num, records.last)
  end.compact
  records
end

#process(line, line_num, previous = nil) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/nacha/parser.rb', line 49

def process(line, line_num, previous = nil)
  @context.line_errors = []
  parent = previous

  record_types = valid_record_types(parent)

  while record_types
    record = parse_first_by_types(line, record_types)
    break if record || !parent

    record.validate if record
    parent = parent.parent
    record_types = valid_record_types(parent)
  end
  record.line_number = line_num if record
  add_child(parent, record)
  record
end

#valid_record_types(parent) ⇒ Object



68
69
70
71
72
# File 'lib/nacha/parser.rb', line 68

def valid_record_types(parent)
  return DEFAULT_RECORD_TYPES unless parent && parent.respond_to?(:child_record_types)

  parent.child_record_types
end