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,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
module Reader
|
|
6
|
+
class SegmentTok
|
|
7
|
+
include Inspect
|
|
8
|
+
|
|
9
|
+
# @return [Symbol]
|
|
10
|
+
attr_reader :id
|
|
11
|
+
|
|
12
|
+
# @return [Array<CompositeElementTok, SimpleElementTok>]
|
|
13
|
+
attr_reader :element_toks
|
|
14
|
+
|
|
15
|
+
# @return [Position]
|
|
16
|
+
attr_reader :position
|
|
17
|
+
|
|
18
|
+
# @return [Position]
|
|
19
|
+
attr_reader :remainder
|
|
20
|
+
|
|
21
|
+
def initialize(id, element_toks, position, remainder)
|
|
22
|
+
@id, @element_toks, @position, @remainder =
|
|
23
|
+
id, element_toks, position, remainder
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @return [SegmentTok]
|
|
27
|
+
def copy(changes = {})
|
|
28
|
+
SegmentTok.new \
|
|
29
|
+
changes.fetch(:id, @id),
|
|
30
|
+
changes.fetch(:element_toks, @element_toks),
|
|
31
|
+
changes.fetch(:position, @position),
|
|
32
|
+
changes.fetch(:remainder, @remainder)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# :nocov:
|
|
36
|
+
def pretty_print(q)
|
|
37
|
+
q.pp(:segment.cons(@id.cons(@element_toks)))
|
|
38
|
+
end
|
|
39
|
+
# :nocov:
|
|
40
|
+
|
|
41
|
+
def blank?
|
|
42
|
+
@element_toks.all?(&:blank?)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def present?
|
|
46
|
+
not blank?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def to_x12(separators)
|
|
50
|
+
if blank?
|
|
51
|
+
"#{id}#{separators.segment}"
|
|
52
|
+
else
|
|
53
|
+
es = @element_toks.map{|x| x.to_x12(separators) }
|
|
54
|
+
sep = separators.element || "*"
|
|
55
|
+
eos = separators.segment || "~"
|
|
56
|
+
id.cons(es).join(sep).gsub(/#{Regexp.escape(sep)}+$/, "") + eos.strip
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
class << SegmentTok
|
|
62
|
+
# @group Constructors
|
|
63
|
+
#########################################################################
|
|
64
|
+
|
|
65
|
+
# @return [SegmentTok]
|
|
66
|
+
def build(id, element_toks, position, remainder)
|
|
67
|
+
new(id, element_toks, position, remainder)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# @endgroup
|
|
71
|
+
#########################################################################
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
module Reader
|
|
6
|
+
class SimpleElementTok
|
|
7
|
+
include Inspect
|
|
8
|
+
|
|
9
|
+
# @return [String, Object]
|
|
10
|
+
attr_reader :value
|
|
11
|
+
|
|
12
|
+
# @return [Position]
|
|
13
|
+
attr_reader :position
|
|
14
|
+
|
|
15
|
+
# @return [Position]
|
|
16
|
+
attr_reader :remainder
|
|
17
|
+
|
|
18
|
+
def initialize(value, position, remainder)
|
|
19
|
+
@value, @position, @remainder =
|
|
20
|
+
value, position, remainder
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @return [SimpleElementTok]
|
|
24
|
+
def copy(changes = {})
|
|
25
|
+
SimpleElementTok.new \
|
|
26
|
+
changes.fetch(:value, @value),
|
|
27
|
+
changes.fetch(:position, @position),
|
|
28
|
+
changes.fetch(:remainder, @remainder)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def pretty_print(q)
|
|
32
|
+
q.pp(:simple.cons(@value.cons))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def repeated
|
|
36
|
+
RepeatedElementTok.new(self.cons, @position)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def repeated?
|
|
40
|
+
false
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def blank?
|
|
44
|
+
@value.blank?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def present?
|
|
48
|
+
not blank?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def simple?
|
|
52
|
+
true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def composite?
|
|
56
|
+
false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def to_x12(separators)
|
|
60
|
+
@value.to_s
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class << SimpleElementTok
|
|
65
|
+
# @group Constructors
|
|
66
|
+
#########################################################################
|
|
67
|
+
|
|
68
|
+
def build(value, position, remainder)
|
|
69
|
+
new(value, position, remainder)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# @endgroup
|
|
73
|
+
#########################################################################
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# encoding: ISO-8859-1
|
|
3
|
+
module Stupidedi
|
|
4
|
+
using Refinements
|
|
5
|
+
|
|
6
|
+
module Reader
|
|
7
|
+
autoload :Result, "stupidedi/reader/result"
|
|
8
|
+
autoload :Success, "stupidedi/reader/result"
|
|
9
|
+
autoload :Failure, "stupidedi/reader/result"
|
|
10
|
+
|
|
11
|
+
autoload :StreamReader, "stupidedi/reader/stream_reader"
|
|
12
|
+
autoload :TokenReader, "stupidedi/reader/token_reader"
|
|
13
|
+
autoload :Separators, "stupidedi/reader/separators"
|
|
14
|
+
autoload :SegmentDict, "stupidedi/reader/segment_dict"
|
|
15
|
+
|
|
16
|
+
autoload :ComponentElementTok, "stupidedi/reader/tokens/component_element_tok"
|
|
17
|
+
autoload :CompositeElementTok, "stupidedi/reader/tokens/composite_element_tok"
|
|
18
|
+
autoload :RepeatedElementTok, "stupidedi/reader/tokens/repeated_element_tok"
|
|
19
|
+
autoload :SegmentTok, "stupidedi/reader/tokens/segment_tok"
|
|
20
|
+
autoload :SimpleElementTok, "stupidedi/reader/tokens/simple_element_tok"
|
|
21
|
+
|
|
22
|
+
autoload :Input, "stupidedi/reader/input"
|
|
23
|
+
autoload :Position, "stupidedi/reader/position"
|
|
24
|
+
autoload :AbstractInput, "stupidedi/reader/input/abstract_input"
|
|
25
|
+
autoload :DelegatedInput, "stupidedi/reader/input/delegated_input"
|
|
26
|
+
autoload :FileInput, "stupidedi/reader/input/file_input"
|
|
27
|
+
|
|
28
|
+
# @private
|
|
29
|
+
# @return [Regexp]
|
|
30
|
+
R_BASIC = /[A-Z0-9!"&'()*+,.\/:;?= -]/.freeze
|
|
31
|
+
|
|
32
|
+
# @private
|
|
33
|
+
# @return [Regexp]
|
|
34
|
+
R_EXTENDED = /[a-z%@\[\]_{}\\|<>~^`#\$ÀÁÂÄàáâäÈÉÊèéêëÌÍÎìíîïÒÓÔÖòóôöÙÚÛÜùúûüÇçÑñ¿¡]/.freeze
|
|
35
|
+
|
|
36
|
+
# @private
|
|
37
|
+
# @return [Regexp]
|
|
38
|
+
R_EITHER = Regexp.union(R_BASIC, R_EXTENDED).freeze
|
|
39
|
+
|
|
40
|
+
# @private
|
|
41
|
+
# @return [String]
|
|
42
|
+
C_BYTES = (0..255).inject(""){|string, c| string + [c].pack('U') }
|
|
43
|
+
|
|
44
|
+
# @private
|
|
45
|
+
# @return [Hash]
|
|
46
|
+
H_BASIC = C_BYTES.scan(R_BASIC).inject({}){|h,c| h[c] = nil; h }.freeze
|
|
47
|
+
|
|
48
|
+
# @private
|
|
49
|
+
# @return [Hash]
|
|
50
|
+
H_EXTENDED = C_BYTES.scan(R_EXTENDED).inject({}){|h,c| h[c] = nil; h }.freeze
|
|
51
|
+
|
|
52
|
+
# @private
|
|
53
|
+
# @return [Hash]
|
|
54
|
+
H_EITHER = C_BYTES.scan(R_EITHER).inject({}){|h,c| h[c] = nil; h }.freeze
|
|
55
|
+
|
|
56
|
+
# @private
|
|
57
|
+
# @return [Regexp]
|
|
58
|
+
#_CONTROL = Regexp.new("[^#{Regexp.quote(H_EITHER.keys.join)}]")
|
|
59
|
+
|
|
60
|
+
class << self
|
|
61
|
+
# @group Constructors
|
|
62
|
+
#########################################################################
|
|
63
|
+
|
|
64
|
+
# @return [StreamReader]
|
|
65
|
+
def build(input)
|
|
66
|
+
StreamReader.new(Input.build(input))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @endgroup
|
|
70
|
+
#########################################################################
|
|
71
|
+
|
|
72
|
+
# Returns true if `character` does not belong to the extended or basic
|
|
73
|
+
# character set.
|
|
74
|
+
#
|
|
75
|
+
# @see X222.pdf B.1.1.2.4 Control Characters
|
|
76
|
+
def is_control_character?(character)
|
|
77
|
+
not H_EITHER.include?(character)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @private
|
|
81
|
+
# @see X222.pdf B.1.1.2.2 Basic Characters
|
|
82
|
+
def is_basic_character?(character)
|
|
83
|
+
H_BASIC.include?(character)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @private
|
|
87
|
+
# @see X222.pdf B.1.1.2.2 Extended Characters
|
|
88
|
+
def is_extended_character?(character)
|
|
89
|
+
H_EXTENDED.include?(character)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @private
|
|
93
|
+
def has_extended_characters?(string)
|
|
94
|
+
R_EXTENDED =~ string
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @private
|
|
98
|
+
def has_control_characters?(string)
|
|
99
|
+
#_CONTROL =~ string
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# @return [Character]
|
|
103
|
+
# @private
|
|
104
|
+
def basic_characters
|
|
105
|
+
H_BASIC.keys
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# @return [Character]
|
|
109
|
+
# @private
|
|
110
|
+
def extended_characters
|
|
111
|
+
H_EXTENDED.keys
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# @return [Character]
|
|
115
|
+
# @private
|
|
116
|
+
def control_characters
|
|
117
|
+
C_BYTES.split(//) - H_EITHER.keys
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
module Schema
|
|
6
|
+
class AbstractDef
|
|
7
|
+
def usage?
|
|
8
|
+
false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def definition?
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [String]
|
|
16
|
+
abstract :descriptor
|
|
17
|
+
|
|
18
|
+
abstract :required?
|
|
19
|
+
|
|
20
|
+
# Is this an {InterchangeDef}?
|
|
21
|
+
def interchange?
|
|
22
|
+
false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Is this an {FunctionalGroupDef}?
|
|
26
|
+
def functional_group?
|
|
27
|
+
false
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Is this an {TransactionSetDef}?
|
|
31
|
+
def transaction_set?
|
|
32
|
+
false
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Is this a {TableDef}?
|
|
36
|
+
def table?
|
|
37
|
+
false
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Is this a {LoopDef}?
|
|
41
|
+
def loop?
|
|
42
|
+
false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Is this a {SegmentDef}?
|
|
46
|
+
def segment?
|
|
47
|
+
false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Is this a {AbstractElementDef}?
|
|
51
|
+
def element?
|
|
52
|
+
false
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Is this a {CompositeElementDef}?
|
|
56
|
+
def composite?
|
|
57
|
+
false
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Is this a component {SimpleElementDef}?
|
|
61
|
+
def component?
|
|
62
|
+
false
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Is this a repeated {AbstractElementDef}?
|
|
66
|
+
def repeated?
|
|
67
|
+
false
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Is this a non-component {SimpleElementDef}?
|
|
71
|
+
def simple?
|
|
72
|
+
false
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
module Schema
|
|
6
|
+
class AbstractElementDef < AbstractDef
|
|
7
|
+
include Inspect
|
|
8
|
+
|
|
9
|
+
# @return [String]
|
|
10
|
+
attr_reader :id
|
|
11
|
+
|
|
12
|
+
# @return [String]
|
|
13
|
+
attr_reader :name
|
|
14
|
+
|
|
15
|
+
# @return [String]
|
|
16
|
+
attr_reader :description
|
|
17
|
+
|
|
18
|
+
abstract :simple?
|
|
19
|
+
|
|
20
|
+
abstract :composite?
|
|
21
|
+
|
|
22
|
+
# @return [AbstractSet<CodeList>]
|
|
23
|
+
abstract :code_lists
|
|
24
|
+
|
|
25
|
+
# @return [String]
|
|
26
|
+
def descriptor
|
|
27
|
+
"element #{id} #{description}".strip
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def element?
|
|
31
|
+
true
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
module Schema
|
|
6
|
+
class AbstractElementUse < AbstractUse
|
|
7
|
+
include Inspect
|
|
8
|
+
|
|
9
|
+
def_delegators :requirement, :forbidden?, :required?, :optional?
|
|
10
|
+
|
|
11
|
+
def_delegators :definition, :code_lists
|
|
12
|
+
|
|
13
|
+
# @return [Symbol]
|
|
14
|
+
abstract :id
|
|
15
|
+
|
|
16
|
+
# @return [String]
|
|
17
|
+
abstract :name
|
|
18
|
+
|
|
19
|
+
# @return [String]
|
|
20
|
+
abstract :description
|
|
21
|
+
|
|
22
|
+
# @return [ElementReq]
|
|
23
|
+
abstract :requirement
|
|
24
|
+
|
|
25
|
+
# @return [SimpleElementDef, CompositeElementDef]
|
|
26
|
+
abstract :definition
|
|
27
|
+
|
|
28
|
+
abstract :simple?
|
|
29
|
+
|
|
30
|
+
abstract :component?
|
|
31
|
+
|
|
32
|
+
# @return [SimpleElementVal, CompositeElementVal]
|
|
33
|
+
def empty(position)
|
|
34
|
+
definition.empty(self, position)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @return [SimpleElementVal, CompositeElementVal]
|
|
38
|
+
def value(object, position)
|
|
39
|
+
definition.value(object, self, position)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def composite?
|
|
43
|
+
not simple?
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
module Schema
|
|
6
|
+
class AbstractUse
|
|
7
|
+
def usage?
|
|
8
|
+
true
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def definition?
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [Symbol]
|
|
16
|
+
abstract :id
|
|
17
|
+
|
|
18
|
+
# @return [String]
|
|
19
|
+
abstract :descriptor
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
#########################################################################
|
|
23
|
+
|
|
24
|
+
# Is this a {SegmentUse}?
|
|
25
|
+
def segment?
|
|
26
|
+
false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Is this a {AbstractElementUse}?
|
|
30
|
+
def element?
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Is this a {CompositeElementUse}?
|
|
35
|
+
def composite?
|
|
36
|
+
false
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Is this a component {SimpleElementUse}?
|
|
40
|
+
def component?
|
|
41
|
+
false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Is this a repeatable {AbstractUse}?
|
|
45
|
+
def repeated?
|
|
46
|
+
false
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Is this a non-component {SimpleElementUse}?
|
|
50
|
+
def simple?
|
|
51
|
+
false
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# The definitions for these types, like InterchangeDef aren't reused, so
|
|
55
|
+
# they don't have corresponding AbstractUse subclasses.
|
|
56
|
+
#########################################################################
|
|
57
|
+
|
|
58
|
+
def interchange?
|
|
59
|
+
false
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def functional_group?
|
|
63
|
+
false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def transaction_set?
|
|
67
|
+
false
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def table?
|
|
71
|
+
false
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def loop?
|
|
75
|
+
false
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
module Schema
|
|
6
|
+
class CodeList
|
|
7
|
+
include Inspect
|
|
8
|
+
|
|
9
|
+
abstract :external?
|
|
10
|
+
|
|
11
|
+
def internal?
|
|
12
|
+
not external?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class Internal < CodeList
|
|
16
|
+
def_delegators :@hash, :at, :defined_at?
|
|
17
|
+
|
|
18
|
+
def initialize(hash)
|
|
19
|
+
@hash = hash
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @return [Array<String>]
|
|
23
|
+
def codes
|
|
24
|
+
@hash.keys
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def external?
|
|
28
|
+
false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Some elements are qualifiers that select which code list
|
|
32
|
+
# is applicable to the qualified element. For instance, the
|
|
33
|
+
# diagnosis codes in the HI segment are qualified by E1270
|
|
34
|
+
# "Code List Qualifier Code", which indicates which code list
|
|
35
|
+
# should be used to validate the E1271's diagnosis code. It
|
|
36
|
+
# maybe ICD-9, ICD-10, etc.
|
|
37
|
+
#
|
|
38
|
+
# @return [AbstractSet<CodeList>]
|
|
39
|
+
def code_lists(subset = Sets.universal)
|
|
40
|
+
related =
|
|
41
|
+
@hash.select do |k, v|
|
|
42
|
+
subset.include?(k) and v.is_a?(Schema::CodeList)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if subset.finite?
|
|
46
|
+
Sets.build([self]) + related.map{|k,v| v }
|
|
47
|
+
else
|
|
48
|
+
Sets.build([self])
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class External < CodeList
|
|
54
|
+
# @return [String]
|
|
55
|
+
attr_reader :id
|
|
56
|
+
|
|
57
|
+
def initialize(id)
|
|
58
|
+
@id = id
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def external?
|
|
62
|
+
true
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def code_lists(values = Sets.universal)
|
|
66
|
+
Sets.build([self])
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def to_str
|
|
70
|
+
"CodeList.external(#{@id})"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
class << CodeList
|
|
76
|
+
# @group Constructors
|
|
77
|
+
#########################################################################
|
|
78
|
+
|
|
79
|
+
# @return [CodeList::Internal]
|
|
80
|
+
def build(hash)
|
|
81
|
+
# @todo: deprecate
|
|
82
|
+
CodeList::Internal.new(hash)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# @return [CodeList::Internal]
|
|
86
|
+
def internal(hash)
|
|
87
|
+
CodeList::Internal.new(hash)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# @return [CodeList::External]
|
|
91
|
+
def external(id, *ignored)
|
|
92
|
+
CodeList::External.new(id)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# @endgroup
|
|
96
|
+
#########################################################################
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
module Schema
|
|
6
|
+
class ComponentElementUse < AbstractElementUse
|
|
7
|
+
# @return [SimpleElementDef]
|
|
8
|
+
attr_reader :definition
|
|
9
|
+
|
|
10
|
+
def_delegators :definition, :id, :name, :description
|
|
11
|
+
|
|
12
|
+
# @return [ElementReq]
|
|
13
|
+
attr_reader :requirement
|
|
14
|
+
|
|
15
|
+
# @return [CompositeElementDef]
|
|
16
|
+
attr_reader :parent
|
|
17
|
+
|
|
18
|
+
# @return [AbstractSet]
|
|
19
|
+
attr_reader :allowed_values
|
|
20
|
+
|
|
21
|
+
def initialize(definition, requirement, allowed_values, parent)
|
|
22
|
+
@definition, @requirement, @allowed_values, @parent =
|
|
23
|
+
definition, requirement, allowed_values, parent
|
|
24
|
+
|
|
25
|
+
# Delay re-parenting until the entire definition tree has a root
|
|
26
|
+
# to prevent unnecessarily copying objects
|
|
27
|
+
unless parent.nil?
|
|
28
|
+
@definition = @definition.copy(:parent => self)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @return [ComponentElementUse]
|
|
33
|
+
def copy(changes = {})
|
|
34
|
+
ComponentElementUse.new \
|
|
35
|
+
changes.fetch(:definition, @definition),
|
|
36
|
+
changes.fetch(:requirement, @requirement),
|
|
37
|
+
changes.fetch(:allowed_values, @allowed_values),
|
|
38
|
+
changes.fetch(:parent, @parent)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [String]
|
|
42
|
+
def descriptor
|
|
43
|
+
n = parent.parent.parent.element_uses.index{|u| u.eql?(parent.parent) } + 1
|
|
44
|
+
m = parent.component_uses.index{|u| u.eql?(self) } + 1
|
|
45
|
+
"element #{parent.parent.parent.id}#{"%02d-%02d" % [n, m]} #{definition.name}".strip
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @return false
|
|
49
|
+
def repeatable?
|
|
50
|
+
false
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @return true
|
|
54
|
+
def simple?
|
|
55
|
+
true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @return true
|
|
59
|
+
def component?
|
|
60
|
+
true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @return [void]
|
|
64
|
+
def pretty_print(q)
|
|
65
|
+
q.text("ComponentElementUse")
|
|
66
|
+
q.group(2, "(", ")") do
|
|
67
|
+
q.breakable ""
|
|
68
|
+
q.pp @definition
|
|
69
|
+
q.text ","
|
|
70
|
+
q.breakable
|
|
71
|
+
q.pp @requirement
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|