tediparse 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +319 -0
- data/LICENSE +26 -0
- data/README.md +308 -0
- data/Rakefile +33 -0
- data/bin/tediparse +102 -0
- data/doc/Defining.md +97 -0
- data/doc/Generating-Grammars.md +241 -0
- data/doc/Generating.md +332 -0
- data/doc/Navigating.md +670 -0
- data/doc/Parsing.md +133 -0
- data/doc/README.md +51 -0
- data/doc/Serializing.md +100 -0
- data/doc/Tokenizing.md +136 -0
- data/doc/Validating.md +140 -0
- data/lib/ruby/array.rb +226 -0
- data/lib/ruby/blank.rb +52 -0
- data/lib/ruby/exception.rb +14 -0
- data/lib/ruby/hash.rb +14 -0
- data/lib/ruby/module.rb +60 -0
- data/lib/ruby/object.rb +56 -0
- data/lib/ruby/string.rb +89 -0
- data/lib/ruby/to_d.rb +82 -0
- data/lib/ruby/to_date.rb +26 -0
- data/lib/ruby/to_time.rb +21 -0
- data/lib/ruby/try.rb +46 -0
- data/lib/stupidedi/builder.rb +6 -0
- data/lib/stupidedi/color.rb +94 -0
- data/lib/stupidedi/config/code_list_config.rb +45 -0
- data/lib/stupidedi/config/functional_group_config.rb +72 -0
- data/lib/stupidedi/config/interchange_config.rb +86 -0
- data/lib/stupidedi/config/transaction_set_config.rb +73 -0
- data/lib/stupidedi/config.rb +100 -0
- data/lib/stupidedi/either.rb +286 -0
- data/lib/stupidedi/exceptions/invalid_element_error.rb +7 -0
- data/lib/stupidedi/exceptions/invalid_schema_error.rb +7 -0
- data/lib/stupidedi/exceptions/missing_grammar_error.rb +50 -0
- data/lib/stupidedi/exceptions/output_error.rb +7 -0
- data/lib/stupidedi/exceptions/parse_error.rb +7 -0
- data/lib/stupidedi/exceptions/stupidedi_error.rb +7 -0
- data/lib/stupidedi/exceptions/tokenize_error.rb +7 -0
- data/lib/stupidedi/exceptions/zipper_error.rb +7 -0
- data/lib/stupidedi/exceptions.rb +13 -0
- data/lib/stupidedi/inspect.rb +26 -0
- data/lib/stupidedi/interchanges/element_types/separator_val.rb +79 -0
- data/lib/stupidedi/interchanges/element_types/special_val.rb +48 -0
- data/lib/stupidedi/interchanges/element_types.rb +11 -0
- data/lib/stupidedi/interchanges.rb +21 -0
- data/lib/stupidedi/parser/builder_dsl.rb +292 -0
- data/lib/stupidedi/parser/constraint_table.rb +566 -0
- data/lib/stupidedi/parser/generation.rb +147 -0
- data/lib/stupidedi/parser/identifier_stack.rb +248 -0
- data/lib/stupidedi/parser/instruction.rb +112 -0
- data/lib/stupidedi/parser/instruction_table.rb +222 -0
- data/lib/stupidedi/parser/navigation.rb +786 -0
- data/lib/stupidedi/parser/state_machine.rb +62 -0
- data/lib/stupidedi/parser/states/abstract_state.rb +385 -0
- data/lib/stupidedi/parser/states/failure_state.rb +69 -0
- data/lib/stupidedi/parser/states/functional_group_state.rb +101 -0
- data/lib/stupidedi/parser/states/initial_state.rb +62 -0
- data/lib/stupidedi/parser/states/interchange_state.rb +96 -0
- data/lib/stupidedi/parser/states/loop_state.rb +74 -0
- data/lib/stupidedi/parser/states/table_state.rb +90 -0
- data/lib/stupidedi/parser/states/transaction_set_state.rb +120 -0
- data/lib/stupidedi/parser/states/transmission_state.rb +59 -0
- data/lib/stupidedi/parser/tokenization.rb +195 -0
- data/lib/stupidedi/parser.rb +32 -0
- data/lib/stupidedi/reader/input/abstract_input.rb +137 -0
- data/lib/stupidedi/reader/input/delegated_input.rb +112 -0
- data/lib/stupidedi/reader/input/file_input.rb +157 -0
- data/lib/stupidedi/reader/input.rb +31 -0
- data/lib/stupidedi/reader/position.rb +78 -0
- data/lib/stupidedi/reader/result.rb +172 -0
- data/lib/stupidedi/reader/segment_dict.rb +176 -0
- data/lib/stupidedi/reader/separators.rb +90 -0
- data/lib/stupidedi/reader/stream_reader.rb +173 -0
- data/lib/stupidedi/reader/token_reader.rb +465 -0
- data/lib/stupidedi/reader/tokens/component_element_tok.rb +71 -0
- data/lib/stupidedi/reader/tokens/composite_element_tok.rb +85 -0
- data/lib/stupidedi/reader/tokens/repeated_element_tok.rb +74 -0
- data/lib/stupidedi/reader/tokens/segment_tok.rb +74 -0
- data/lib/stupidedi/reader/tokens/simple_element_tok.rb +76 -0
- data/lib/stupidedi/reader.rb +121 -0
- data/lib/stupidedi/schema/abstract_def.rb +76 -0
- data/lib/stupidedi/schema/abstract_element_def.rb +35 -0
- data/lib/stupidedi/schema/abstract_element_use.rb +47 -0
- data/lib/stupidedi/schema/abstract_use.rb +79 -0
- data/lib/stupidedi/schema/code_list.rb +99 -0
- data/lib/stupidedi/schema/component_element_use.rb +76 -0
- data/lib/stupidedi/schema/composite_element_def.rb +103 -0
- data/lib/stupidedi/schema/composite_element_use.rb +78 -0
- data/lib/stupidedi/schema/element_req.rb +57 -0
- data/lib/stupidedi/schema/functional_group_def.rb +124 -0
- data/lib/stupidedi/schema/generation/definition_generator.rb +139 -0
- data/lib/stupidedi/schema/generation/element_generator.rb +221 -0
- data/lib/stupidedi/schema/generation/flat_file_reader.rb +551 -0
- data/lib/stupidedi/schema/generation/functional_group_generator.rb +64 -0
- data/lib/stupidedi/schema/generation/interchange_generator.rb +145 -0
- data/lib/stupidedi/schema/generation/master_loader_generator.rb +121 -0
- data/lib/stupidedi/schema/generation/models.rb +85 -0
- data/lib/stupidedi/schema/generation/module_loader_generator.rb +64 -0
- data/lib/stupidedi/schema/generation/registration_generator.rb +230 -0
- data/lib/stupidedi/schema/generation/runner.rb +161 -0
- data/lib/stupidedi/schema/generation/segment_generator.rb +130 -0
- data/lib/stupidedi/schema/generation/support.rb +78 -0
- data/lib/stupidedi/schema/generation/support_modules_generator.rb +126 -0
- data/lib/stupidedi/schema/generation/version_modules.rb +35 -0
- data/lib/stupidedi/schema/generation.rb +94 -0
- data/lib/stupidedi/schema/interchange_def.rb +103 -0
- data/lib/stupidedi/schema/loop_def.rb +156 -0
- data/lib/stupidedi/schema/repeat_count.rb +86 -0
- data/lib/stupidedi/schema/segment_def.rb +122 -0
- data/lib/stupidedi/schema/segment_req.rb +46 -0
- data/lib/stupidedi/schema/segment_use.rb +99 -0
- data/lib/stupidedi/schema/simple_element_def.rb +51 -0
- data/lib/stupidedi/schema/simple_element_use.rb +83 -0
- data/lib/stupidedi/schema/syntax_note.rb +52 -0
- data/lib/stupidedi/schema/table_def.rb +178 -0
- data/lib/stupidedi/schema/transaction_set_def.rb +125 -0
- data/lib/stupidedi/schema.rb +30 -0
- data/lib/stupidedi/sets.rb +42 -0
- data/lib/stupidedi/transaction_sets/builder/dsl.rb +192 -0
- data/lib/stupidedi/transaction_sets/builder.rb +188 -0
- data/lib/stupidedi/transaction_sets/common/implementations/element_reqs.rb +37 -0
- data/lib/stupidedi/transaction_sets/common/implementations/segment_reqs.rb +31 -0
- data/lib/stupidedi/transaction_sets/common/implementations.rb +11 -0
- data/lib/stupidedi/transaction_sets/common.rb +8 -0
- data/lib/stupidedi/transaction_sets/validation/ambiguity.rb +395 -0
- data/lib/stupidedi/transaction_sets/validation/implementation.rb +12 -0
- data/lib/stupidedi/transaction_sets/validation.rb +9 -0
- data/lib/stupidedi/transaction_sets.rb +25 -0
- data/lib/stupidedi/values/abstract_element_val.rb +19 -0
- data/lib/stupidedi/values/abstract_val.rb +133 -0
- data/lib/stupidedi/values/composite_element_val.rb +102 -0
- data/lib/stupidedi/values/functional_group_val.rb +105 -0
- data/lib/stupidedi/values/interchange_val.rb +102 -0
- data/lib/stupidedi/values/invalid_envelope_val.rb +61 -0
- data/lib/stupidedi/values/invalid_segment_val.rb +89 -0
- data/lib/stupidedi/values/loop_val.rb +73 -0
- data/lib/stupidedi/values/repeated_element_val.rb +113 -0
- data/lib/stupidedi/values/segment_val.rb +105 -0
- data/lib/stupidedi/values/segment_val_group.rb +20 -0
- data/lib/stupidedi/values/simple_element_val.rb +80 -0
- data/lib/stupidedi/values/table_val.rb +69 -0
- data/lib/stupidedi/values/transaction_set_val.rb +69 -0
- data/lib/stupidedi/values/transmission_val.rb +56 -0
- data/lib/stupidedi/values.rb +22 -0
- data/lib/stupidedi/version.rb +4 -0
- data/lib/stupidedi/versions/common/element_reqs.rb +13 -0
- data/lib/stupidedi/versions/common/element_types/an.rb +386 -0
- data/lib/stupidedi/versions/common/element_types/dt.rb +572 -0
- data/lib/stupidedi/versions/common/element_types/id.rb +304 -0
- data/lib/stupidedi/versions/common/element_types/nn.rb +312 -0
- data/lib/stupidedi/versions/common/element_types/operators.rb +128 -0
- data/lib/stupidedi/versions/common/element_types/r.rb +342 -0
- data/lib/stupidedi/versions/common/element_types/simple_element.rb +73 -0
- data/lib/stupidedi/versions/common/element_types/tm.rb +347 -0
- data/lib/stupidedi/versions/common/element_types.rb +29 -0
- data/lib/stupidedi/versions/common/segment_reqs.rb +15 -0
- data/lib/stupidedi/versions/common/syntax_notes.rb +172 -0
- data/lib/stupidedi/versions/common.rb +11 -0
- data/lib/stupidedi/versions.rb +25 -0
- data/lib/stupidedi/writer/claredi.rb +178 -0
- data/lib/stupidedi/writer/default.rb +119 -0
- data/lib/stupidedi/writer.rb +7 -0
- data/lib/stupidedi/zipper/abstract_cursor.rb +351 -0
- data/lib/stupidedi/zipper/dangling_cursor.rb +103 -0
- data/lib/stupidedi/zipper/edited_cursor.rb +157 -0
- data/lib/stupidedi/zipper/memoized_cursor.rb +133 -0
- data/lib/stupidedi/zipper/path.rb +132 -0
- data/lib/stupidedi/zipper/root_cursor.rb +120 -0
- data/lib/stupidedi/zipper/stack_cursor.rb +107 -0
- data/lib/stupidedi/zipper.rb +45 -0
- data/lib/stupidedi.rb +69 -0
- data/lib/tediparse.rb +1 -0
- metadata +249 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
module Color
|
|
6
|
+
def self.ansi
|
|
7
|
+
@__ansi ||=
|
|
8
|
+
if defined?(::Term::ANSIColor)
|
|
9
|
+
Wrapper.new(::Term::ANSIColor)
|
|
10
|
+
else
|
|
11
|
+
Wrapper.new(Stub)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def ansi
|
|
16
|
+
Color.ansi
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @private
|
|
20
|
+
module Stub
|
|
21
|
+
METHODS = %w(bold clear reset dark underscore blink negative concealed
|
|
22
|
+
black red green yellow blue magenta cyan white on_black
|
|
23
|
+
on_red on_green on_yellow on_blue on_magenta on_cyan on_white)
|
|
24
|
+
|
|
25
|
+
METHODS.each do |name|
|
|
26
|
+
instance_eval(<<-RUBY, __FILE__, __LINE__)
|
|
27
|
+
def #{name}(string)
|
|
28
|
+
string
|
|
29
|
+
end
|
|
30
|
+
RUBY
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class Wrapper
|
|
35
|
+
def initialize(base)
|
|
36
|
+
@base = base
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def noop(string)
|
|
40
|
+
string
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def invalid(string)
|
|
44
|
+
red(bold(string))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def element(string)
|
|
48
|
+
black(string)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def required(string)
|
|
52
|
+
bold(string)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def optional(string)
|
|
56
|
+
dark(white(string))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def forbidden(string)
|
|
60
|
+
noop(string)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def repeated(string)
|
|
64
|
+
black(string)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def composite(string)
|
|
68
|
+
black(string)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def segment(string)
|
|
72
|
+
magenta(string)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def loop(string)
|
|
76
|
+
yellow(string)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def table(string)
|
|
80
|
+
yellow(string)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def envelope(string)
|
|
84
|
+
yellow(string)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
def method_missing(name, *args)
|
|
90
|
+
@base.__send__(name, *args)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
class Config
|
|
6
|
+
class CodeListConfig
|
|
7
|
+
include Inspect
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@table = Hash.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def customize(&block)
|
|
14
|
+
tap(&block)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def register(id, &constructor)
|
|
18
|
+
@table[id] = constructor
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def defined_at?(id)
|
|
22
|
+
@table.defined_at?(id)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def at(id)
|
|
26
|
+
@table[id].call
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @return [void]
|
|
30
|
+
def pretty_print(q)
|
|
31
|
+
q.text "CodeListConfig"
|
|
32
|
+
q.group(2, "(", ")") do
|
|
33
|
+
q.breakable ""
|
|
34
|
+
@table.keys.each do |e|
|
|
35
|
+
unless q.current_group.first?
|
|
36
|
+
q.text ","
|
|
37
|
+
q.breakable
|
|
38
|
+
end
|
|
39
|
+
q.pp e
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
class Config
|
|
6
|
+
#
|
|
7
|
+
# The functional group segments (GS/GE) and the segments contained by that
|
|
8
|
+
# functional group are versioned separately from the interchange control
|
|
9
|
+
# segments (ISA/ISE). The functional group version is informally referred to
|
|
10
|
+
# as the EDI version (5010, 4010, etc). Each version indicates the segment
|
|
11
|
+
# dictionary being used and the grammar of the functional group. Only the GS
|
|
12
|
+
# and GE segments are described in the HIPAA guides, but the functional
|
|
13
|
+
# group header and footer may consist of other segments.
|
|
14
|
+
#
|
|
15
|
+
# Because the interchange and functional group are versioned independently,
|
|
16
|
+
# it may be possible, for instance, to send a 4010 transaction set within a
|
|
17
|
+
# 5010 envelope, depending on forward- and backward-comatibility.
|
|
18
|
+
#
|
|
19
|
+
# @see http://x12.org/rfis/ "Relations Between the ISA and GS Segments.PDF"
|
|
20
|
+
#
|
|
21
|
+
class FunctionalGroupConfig
|
|
22
|
+
include Inspect
|
|
23
|
+
|
|
24
|
+
# @return [Hash<String, FunctionalGroupDef>]
|
|
25
|
+
attr_reader :table
|
|
26
|
+
|
|
27
|
+
def_delegators :@table, :defined_at?, :empty?
|
|
28
|
+
|
|
29
|
+
def initialize
|
|
30
|
+
@table = Hash.new
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def customize(&block)
|
|
34
|
+
tap(&block)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @return [void]
|
|
38
|
+
def register(version, definition = nil, &constructor)
|
|
39
|
+
if block_given?
|
|
40
|
+
@table[version] = constructor
|
|
41
|
+
elsif definition.nil?
|
|
42
|
+
raise ArgumentError,
|
|
43
|
+
"FunctionalGroupConfig#register(#{version.inspect}) was called " \
|
|
44
|
+
"with no definition and no block"
|
|
45
|
+
else
|
|
46
|
+
@table[version] = definition
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @return [FunctionalGroupDef]
|
|
51
|
+
def at(version)
|
|
52
|
+
x = @table[version]
|
|
53
|
+
x.is_a?(Proc) ? x.call : x
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @return [void]
|
|
57
|
+
def pretty_print(q)
|
|
58
|
+
q.text "FunctionalGroupConfig"
|
|
59
|
+
q.group(2, "(", ")") do
|
|
60
|
+
q.breakable ""
|
|
61
|
+
@table.keys.each do |e|
|
|
62
|
+
unless q.current_group.first?
|
|
63
|
+
q.text ","
|
|
64
|
+
q.breakable
|
|
65
|
+
end
|
|
66
|
+
q.pp e
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
class Config
|
|
6
|
+
#
|
|
7
|
+
# The interchange control segments (ISA/ISE) are versioned independently
|
|
8
|
+
# from the functional group segments (GS/GE). Because different interchange
|
|
9
|
+
# versions can have unique grammars, this table serves as an indirection.
|
|
10
|
+
#
|
|
11
|
+
# Opinion: The interchange version is encoded within the ISA segment, whose
|
|
12
|
+
# definition is recursively dependent on the interchange version. Worse yet,
|
|
13
|
+
# the version is encoded as the fourteenth element (in versions 00501 and
|
|
14
|
+
# 00401), instead of say, the 1st element.
|
|
15
|
+
#
|
|
16
|
+
# This seems to indicate the versioning was an afterthought. The same
|
|
17
|
+
# thought process was applied when versioning the functional group segments,
|
|
18
|
+
# which has the version encoded in GS08.
|
|
19
|
+
#
|
|
20
|
+
# The best we can do to cope with this is to presume the ISA and GS segments
|
|
21
|
+
# have an underlying grammar that won't change between versions. We do this
|
|
22
|
+
# by parsing 12 things following "ISA", using the 12th thing as the version
|
|
23
|
+
# number, and then starting over at "ISA" and parsing with actual grammar.
|
|
24
|
+
# Then the grammar can specify which elements specify delimiters and all the
|
|
25
|
+
# other parts of the interchange header, like the TA1 segment.
|
|
26
|
+
#
|
|
27
|
+
# @see http://x12.org/rfis/ "Relations Between the ISA and GS Segments.PDF"
|
|
28
|
+
#
|
|
29
|
+
class InterchangeConfig
|
|
30
|
+
include Inspect
|
|
31
|
+
|
|
32
|
+
# @return [Hash<String, InterchangeDef>]
|
|
33
|
+
attr_reader :table
|
|
34
|
+
|
|
35
|
+
def_delegators :@table, :defined_at?, :empty?
|
|
36
|
+
|
|
37
|
+
def initialize
|
|
38
|
+
@table = Hash.new
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def customize(&block)
|
|
42
|
+
tap(&block)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# @example
|
|
47
|
+
# table = InterchangeConfig.new
|
|
48
|
+
#
|
|
49
|
+
# table.register("DEMO01") { MyApp::Envelopes::Demo }
|
|
50
|
+
#
|
|
51
|
+
# @return [void]
|
|
52
|
+
def register(version, definition = nil, &constructor)
|
|
53
|
+
if block_given?
|
|
54
|
+
@table[version] = constructor
|
|
55
|
+
elsif definition.nil?
|
|
56
|
+
raise ArgumentError,
|
|
57
|
+
"InterchangeConfig#register(#{version.inspect}) was called " \
|
|
58
|
+
"with no definition and no block"
|
|
59
|
+
else
|
|
60
|
+
@table[version] = definition
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @return [InterchangeDef]
|
|
65
|
+
def at(version)
|
|
66
|
+
x = @table[version]
|
|
67
|
+
x.is_a?(Proc) ? x.call : x
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# @return [void]
|
|
71
|
+
def pretty_print(q)
|
|
72
|
+
q.text "InterchangeConfig"
|
|
73
|
+
q.group(2, "(", ")") do
|
|
74
|
+
q.breakable ""
|
|
75
|
+
@table.keys.each do |e|
|
|
76
|
+
unless q.current_group.first?
|
|
77
|
+
q.text ","
|
|
78
|
+
q.breakable
|
|
79
|
+
end
|
|
80
|
+
q.pp e
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
class Config
|
|
6
|
+
#
|
|
7
|
+
# The implementation version specified in GS08 (or ST03) indicates which
|
|
8
|
+
# implementation guide governs the transaction.
|
|
9
|
+
#
|
|
10
|
+
# Note we can't look only at ST01 to link "837" to our definition of
|
|
11
|
+
# 837P from the HIPAA guide without also considering "005010X222", because
|
|
12
|
+
# thereare several different "837"s (including "005010X223", etc)
|
|
13
|
+
#
|
|
14
|
+
class TransactionSetConfig
|
|
15
|
+
include Inspect
|
|
16
|
+
|
|
17
|
+
# @return [Hash<[GS08/ST03, GS01, ST01], TransactionSetDef>]
|
|
18
|
+
attr_reader :table
|
|
19
|
+
|
|
20
|
+
def initialize
|
|
21
|
+
@table = Hash.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def customize(&block)
|
|
25
|
+
tap(&block)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [void]
|
|
29
|
+
def register(gs08, gs01, st01, definition = nil, &constructor)
|
|
30
|
+
if block_given?
|
|
31
|
+
@table[Array[gs08, gs01, st01]] = constructor
|
|
32
|
+
elsif definition.nil?
|
|
33
|
+
raise ArgumentError,
|
|
34
|
+
"TransactionSetConfig#register(#{gs08.inspect}, #{gs01.inspect}, " \
|
|
35
|
+
"#{st01.inspect}) was called with no definition and no block"
|
|
36
|
+
else
|
|
37
|
+
@table[Array[gs08, gs01, st01]] = definition
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [TransactionSetDef]
|
|
42
|
+
def at(gs08, gs01, st01)
|
|
43
|
+
x = @table[Array[gs08, gs01, st01]]
|
|
44
|
+
x.is_a?(Proc) ? x.call : x
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def defined_at?(gs08, gs01, st01)
|
|
48
|
+
@table.defined_at?([gs08, gs01, st01])
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def empty?
|
|
52
|
+
@table.empty?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @return [void]
|
|
56
|
+
# :nocov:
|
|
57
|
+
def pretty_print(q)
|
|
58
|
+
q.text "TransactionSetConfig"
|
|
59
|
+
q.group(2, "(", ")") do
|
|
60
|
+
q.breakable ""
|
|
61
|
+
@table.keys.each do |e|
|
|
62
|
+
unless q.current_group.first?
|
|
63
|
+
q.text ","
|
|
64
|
+
q.breakable
|
|
65
|
+
end
|
|
66
|
+
q.pp e
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
# :nocov:
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
class Config
|
|
6
|
+
autoload :CodeListConfig, "stupidedi/config/code_list_config"
|
|
7
|
+
autoload :FunctionalGroupConfig, "stupidedi/config/functional_group_config"
|
|
8
|
+
autoload :InterchangeConfig, "stupidedi/config/interchange_config"
|
|
9
|
+
autoload :TransactionSetConfig, "stupidedi/config/transaction_set_config"
|
|
10
|
+
|
|
11
|
+
include Inspect
|
|
12
|
+
|
|
13
|
+
# @return [InterchangeConfig]
|
|
14
|
+
attr_reader :interchange
|
|
15
|
+
|
|
16
|
+
# @return [FunctionalGroupConfig]
|
|
17
|
+
attr_reader :functional_group
|
|
18
|
+
|
|
19
|
+
# @return [TransactionSetConfig]
|
|
20
|
+
attr_reader :transaction_set
|
|
21
|
+
|
|
22
|
+
# @return [CodeListConfig]
|
|
23
|
+
attr_reader :code_list
|
|
24
|
+
|
|
25
|
+
def initialize
|
|
26
|
+
@interchange = InterchangeConfig.new
|
|
27
|
+
@functional_group = FunctionalGroupConfig.new
|
|
28
|
+
@transaction_set = TransactionSetConfig.new
|
|
29
|
+
@code_list = CodeListConfig.new
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def customize(&block)
|
|
33
|
+
tap(&block)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @return [void]
|
|
37
|
+
def pretty_print(q)
|
|
38
|
+
q.text "Config"
|
|
39
|
+
q.group 2, "(", ")" do
|
|
40
|
+
q.breakable ""
|
|
41
|
+
|
|
42
|
+
q.pp @interchange
|
|
43
|
+
q.text ","
|
|
44
|
+
q.breakable
|
|
45
|
+
|
|
46
|
+
q.pp @functional_group
|
|
47
|
+
q.text ","
|
|
48
|
+
q.breakable
|
|
49
|
+
|
|
50
|
+
q.pp @transaction_set
|
|
51
|
+
q.text ","
|
|
52
|
+
q.breakable
|
|
53
|
+
|
|
54
|
+
q.pp @code_list
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class << Config
|
|
60
|
+
###########################################################################
|
|
61
|
+
# @group Constructors
|
|
62
|
+
|
|
63
|
+
# Returns an empty Config.
|
|
64
|
+
#
|
|
65
|
+
# tediparse does not ship with X12 grammars or transaction-set definitions
|
|
66
|
+
# — those are X12 IP that the gem is not licensed to redistribute. This
|
|
67
|
+
# method is preserved for source compatibility with upstream stupidedi
|
|
68
|
+
# callers; an empty Config means parser-driven lookups produce a
|
|
69
|
+
# FailureState whose reason is
|
|
70
|
+
# +Stupidedi::Exceptions::MissingGrammarError::DEFAULT_MESSAGE+.
|
|
71
|
+
#
|
|
72
|
+
# Register your own grammar with +#customize+ before parsing. See the
|
|
73
|
+
# README and +spec/support/synthetic/demo.rb+ for an authoring example.
|
|
74
|
+
#
|
|
75
|
+
# @return [Config]
|
|
76
|
+
def default
|
|
77
|
+
new
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# See {.default}. Preserved for source compatibility; returns an empty
|
|
81
|
+
# Config built atop +base+ so existing call sites that compose
|
|
82
|
+
# configurations (e.g. +Config.hipaa(my_base)+) keep working.
|
|
83
|
+
#
|
|
84
|
+
# @return [Config]
|
|
85
|
+
def hipaa(base = default)
|
|
86
|
+
base
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# See {.default}. Preserved for source compatibility; returns the +base+
|
|
90
|
+
# unmodified.
|
|
91
|
+
#
|
|
92
|
+
# @return [Config]
|
|
93
|
+
def contrib(base = default)
|
|
94
|
+
base
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @endgroup
|
|
98
|
+
###########################################################################
|
|
99
|
+
end
|
|
100
|
+
end
|