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.
Files changed (176) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +319 -0
  3. data/LICENSE +26 -0
  4. data/README.md +308 -0
  5. data/Rakefile +33 -0
  6. data/bin/tediparse +102 -0
  7. data/doc/Defining.md +97 -0
  8. data/doc/Generating-Grammars.md +241 -0
  9. data/doc/Generating.md +332 -0
  10. data/doc/Navigating.md +670 -0
  11. data/doc/Parsing.md +133 -0
  12. data/doc/README.md +51 -0
  13. data/doc/Serializing.md +100 -0
  14. data/doc/Tokenizing.md +136 -0
  15. data/doc/Validating.md +140 -0
  16. data/lib/ruby/array.rb +226 -0
  17. data/lib/ruby/blank.rb +52 -0
  18. data/lib/ruby/exception.rb +14 -0
  19. data/lib/ruby/hash.rb +14 -0
  20. data/lib/ruby/module.rb +60 -0
  21. data/lib/ruby/object.rb +56 -0
  22. data/lib/ruby/string.rb +89 -0
  23. data/lib/ruby/to_d.rb +82 -0
  24. data/lib/ruby/to_date.rb +26 -0
  25. data/lib/ruby/to_time.rb +21 -0
  26. data/lib/ruby/try.rb +46 -0
  27. data/lib/stupidedi/builder.rb +6 -0
  28. data/lib/stupidedi/color.rb +94 -0
  29. data/lib/stupidedi/config/code_list_config.rb +45 -0
  30. data/lib/stupidedi/config/functional_group_config.rb +72 -0
  31. data/lib/stupidedi/config/interchange_config.rb +86 -0
  32. data/lib/stupidedi/config/transaction_set_config.rb +73 -0
  33. data/lib/stupidedi/config.rb +100 -0
  34. data/lib/stupidedi/either.rb +286 -0
  35. data/lib/stupidedi/exceptions/invalid_element_error.rb +7 -0
  36. data/lib/stupidedi/exceptions/invalid_schema_error.rb +7 -0
  37. data/lib/stupidedi/exceptions/missing_grammar_error.rb +50 -0
  38. data/lib/stupidedi/exceptions/output_error.rb +7 -0
  39. data/lib/stupidedi/exceptions/parse_error.rb +7 -0
  40. data/lib/stupidedi/exceptions/stupidedi_error.rb +7 -0
  41. data/lib/stupidedi/exceptions/tokenize_error.rb +7 -0
  42. data/lib/stupidedi/exceptions/zipper_error.rb +7 -0
  43. data/lib/stupidedi/exceptions.rb +13 -0
  44. data/lib/stupidedi/inspect.rb +26 -0
  45. data/lib/stupidedi/interchanges/element_types/separator_val.rb +79 -0
  46. data/lib/stupidedi/interchanges/element_types/special_val.rb +48 -0
  47. data/lib/stupidedi/interchanges/element_types.rb +11 -0
  48. data/lib/stupidedi/interchanges.rb +21 -0
  49. data/lib/stupidedi/parser/builder_dsl.rb +292 -0
  50. data/lib/stupidedi/parser/constraint_table.rb +566 -0
  51. data/lib/stupidedi/parser/generation.rb +147 -0
  52. data/lib/stupidedi/parser/identifier_stack.rb +248 -0
  53. data/lib/stupidedi/parser/instruction.rb +112 -0
  54. data/lib/stupidedi/parser/instruction_table.rb +222 -0
  55. data/lib/stupidedi/parser/navigation.rb +786 -0
  56. data/lib/stupidedi/parser/state_machine.rb +62 -0
  57. data/lib/stupidedi/parser/states/abstract_state.rb +385 -0
  58. data/lib/stupidedi/parser/states/failure_state.rb +69 -0
  59. data/lib/stupidedi/parser/states/functional_group_state.rb +101 -0
  60. data/lib/stupidedi/parser/states/initial_state.rb +62 -0
  61. data/lib/stupidedi/parser/states/interchange_state.rb +96 -0
  62. data/lib/stupidedi/parser/states/loop_state.rb +74 -0
  63. data/lib/stupidedi/parser/states/table_state.rb +90 -0
  64. data/lib/stupidedi/parser/states/transaction_set_state.rb +120 -0
  65. data/lib/stupidedi/parser/states/transmission_state.rb +59 -0
  66. data/lib/stupidedi/parser/tokenization.rb +195 -0
  67. data/lib/stupidedi/parser.rb +32 -0
  68. data/lib/stupidedi/reader/input/abstract_input.rb +137 -0
  69. data/lib/stupidedi/reader/input/delegated_input.rb +112 -0
  70. data/lib/stupidedi/reader/input/file_input.rb +157 -0
  71. data/lib/stupidedi/reader/input.rb +31 -0
  72. data/lib/stupidedi/reader/position.rb +78 -0
  73. data/lib/stupidedi/reader/result.rb +172 -0
  74. data/lib/stupidedi/reader/segment_dict.rb +176 -0
  75. data/lib/stupidedi/reader/separators.rb +90 -0
  76. data/lib/stupidedi/reader/stream_reader.rb +173 -0
  77. data/lib/stupidedi/reader/token_reader.rb +465 -0
  78. data/lib/stupidedi/reader/tokens/component_element_tok.rb +71 -0
  79. data/lib/stupidedi/reader/tokens/composite_element_tok.rb +85 -0
  80. data/lib/stupidedi/reader/tokens/repeated_element_tok.rb +74 -0
  81. data/lib/stupidedi/reader/tokens/segment_tok.rb +74 -0
  82. data/lib/stupidedi/reader/tokens/simple_element_tok.rb +76 -0
  83. data/lib/stupidedi/reader.rb +121 -0
  84. data/lib/stupidedi/schema/abstract_def.rb +76 -0
  85. data/lib/stupidedi/schema/abstract_element_def.rb +35 -0
  86. data/lib/stupidedi/schema/abstract_element_use.rb +47 -0
  87. data/lib/stupidedi/schema/abstract_use.rb +79 -0
  88. data/lib/stupidedi/schema/code_list.rb +99 -0
  89. data/lib/stupidedi/schema/component_element_use.rb +76 -0
  90. data/lib/stupidedi/schema/composite_element_def.rb +103 -0
  91. data/lib/stupidedi/schema/composite_element_use.rb +78 -0
  92. data/lib/stupidedi/schema/element_req.rb +57 -0
  93. data/lib/stupidedi/schema/functional_group_def.rb +124 -0
  94. data/lib/stupidedi/schema/generation/definition_generator.rb +139 -0
  95. data/lib/stupidedi/schema/generation/element_generator.rb +221 -0
  96. data/lib/stupidedi/schema/generation/flat_file_reader.rb +551 -0
  97. data/lib/stupidedi/schema/generation/functional_group_generator.rb +64 -0
  98. data/lib/stupidedi/schema/generation/interchange_generator.rb +145 -0
  99. data/lib/stupidedi/schema/generation/master_loader_generator.rb +121 -0
  100. data/lib/stupidedi/schema/generation/models.rb +85 -0
  101. data/lib/stupidedi/schema/generation/module_loader_generator.rb +64 -0
  102. data/lib/stupidedi/schema/generation/registration_generator.rb +230 -0
  103. data/lib/stupidedi/schema/generation/runner.rb +161 -0
  104. data/lib/stupidedi/schema/generation/segment_generator.rb +130 -0
  105. data/lib/stupidedi/schema/generation/support.rb +78 -0
  106. data/lib/stupidedi/schema/generation/support_modules_generator.rb +126 -0
  107. data/lib/stupidedi/schema/generation/version_modules.rb +35 -0
  108. data/lib/stupidedi/schema/generation.rb +94 -0
  109. data/lib/stupidedi/schema/interchange_def.rb +103 -0
  110. data/lib/stupidedi/schema/loop_def.rb +156 -0
  111. data/lib/stupidedi/schema/repeat_count.rb +86 -0
  112. data/lib/stupidedi/schema/segment_def.rb +122 -0
  113. data/lib/stupidedi/schema/segment_req.rb +46 -0
  114. data/lib/stupidedi/schema/segment_use.rb +99 -0
  115. data/lib/stupidedi/schema/simple_element_def.rb +51 -0
  116. data/lib/stupidedi/schema/simple_element_use.rb +83 -0
  117. data/lib/stupidedi/schema/syntax_note.rb +52 -0
  118. data/lib/stupidedi/schema/table_def.rb +178 -0
  119. data/lib/stupidedi/schema/transaction_set_def.rb +125 -0
  120. data/lib/stupidedi/schema.rb +30 -0
  121. data/lib/stupidedi/sets.rb +42 -0
  122. data/lib/stupidedi/transaction_sets/builder/dsl.rb +192 -0
  123. data/lib/stupidedi/transaction_sets/builder.rb +188 -0
  124. data/lib/stupidedi/transaction_sets/common/implementations/element_reqs.rb +37 -0
  125. data/lib/stupidedi/transaction_sets/common/implementations/segment_reqs.rb +31 -0
  126. data/lib/stupidedi/transaction_sets/common/implementations.rb +11 -0
  127. data/lib/stupidedi/transaction_sets/common.rb +8 -0
  128. data/lib/stupidedi/transaction_sets/validation/ambiguity.rb +395 -0
  129. data/lib/stupidedi/transaction_sets/validation/implementation.rb +12 -0
  130. data/lib/stupidedi/transaction_sets/validation.rb +9 -0
  131. data/lib/stupidedi/transaction_sets.rb +25 -0
  132. data/lib/stupidedi/values/abstract_element_val.rb +19 -0
  133. data/lib/stupidedi/values/abstract_val.rb +133 -0
  134. data/lib/stupidedi/values/composite_element_val.rb +102 -0
  135. data/lib/stupidedi/values/functional_group_val.rb +105 -0
  136. data/lib/stupidedi/values/interchange_val.rb +102 -0
  137. data/lib/stupidedi/values/invalid_envelope_val.rb +61 -0
  138. data/lib/stupidedi/values/invalid_segment_val.rb +89 -0
  139. data/lib/stupidedi/values/loop_val.rb +73 -0
  140. data/lib/stupidedi/values/repeated_element_val.rb +113 -0
  141. data/lib/stupidedi/values/segment_val.rb +105 -0
  142. data/lib/stupidedi/values/segment_val_group.rb +20 -0
  143. data/lib/stupidedi/values/simple_element_val.rb +80 -0
  144. data/lib/stupidedi/values/table_val.rb +69 -0
  145. data/lib/stupidedi/values/transaction_set_val.rb +69 -0
  146. data/lib/stupidedi/values/transmission_val.rb +56 -0
  147. data/lib/stupidedi/values.rb +22 -0
  148. data/lib/stupidedi/version.rb +4 -0
  149. data/lib/stupidedi/versions/common/element_reqs.rb +13 -0
  150. data/lib/stupidedi/versions/common/element_types/an.rb +386 -0
  151. data/lib/stupidedi/versions/common/element_types/dt.rb +572 -0
  152. data/lib/stupidedi/versions/common/element_types/id.rb +304 -0
  153. data/lib/stupidedi/versions/common/element_types/nn.rb +312 -0
  154. data/lib/stupidedi/versions/common/element_types/operators.rb +128 -0
  155. data/lib/stupidedi/versions/common/element_types/r.rb +342 -0
  156. data/lib/stupidedi/versions/common/element_types/simple_element.rb +73 -0
  157. data/lib/stupidedi/versions/common/element_types/tm.rb +347 -0
  158. data/lib/stupidedi/versions/common/element_types.rb +29 -0
  159. data/lib/stupidedi/versions/common/segment_reqs.rb +15 -0
  160. data/lib/stupidedi/versions/common/syntax_notes.rb +172 -0
  161. data/lib/stupidedi/versions/common.rb +11 -0
  162. data/lib/stupidedi/versions.rb +25 -0
  163. data/lib/stupidedi/writer/claredi.rb +178 -0
  164. data/lib/stupidedi/writer/default.rb +119 -0
  165. data/lib/stupidedi/writer.rb +7 -0
  166. data/lib/stupidedi/zipper/abstract_cursor.rb +351 -0
  167. data/lib/stupidedi/zipper/dangling_cursor.rb +103 -0
  168. data/lib/stupidedi/zipper/edited_cursor.rb +157 -0
  169. data/lib/stupidedi/zipper/memoized_cursor.rb +133 -0
  170. data/lib/stupidedi/zipper/path.rb +132 -0
  171. data/lib/stupidedi/zipper/root_cursor.rb +120 -0
  172. data/lib/stupidedi/zipper/stack_cursor.rb +107 -0
  173. data/lib/stupidedi/zipper.rb +45 -0
  174. data/lib/stupidedi.rb +69 -0
  175. data/lib/tediparse.rb +1 -0
  176. 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