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,386 @@
1
+ # frozen_string_literal: true
2
+ module Stupidedi
3
+ using Refinements
4
+
5
+ module Versions
6
+ module Common
7
+ module ElementTypes
8
+ class AN < SimpleElementDef
9
+ DATE_FORMAT_SINGLE =
10
+ {"CC" => "%C",
11
+ #"CD" => "MMMYYYY", # Month and Year Expressed in Format MMMYYYY
12
+ "CM" => "%Y%m",
13
+ #"CQ" => "CCYYQ", # Date in Format CCYYQ
14
+ "CY" => "%Y",
15
+ "D6" => "%y%m%d",
16
+ "D8" => "%Y%m%d",
17
+ "DB" => "%m%d%Y",
18
+ "DD" => "%d",
19
+ "DT" => "%Y%m%d%H%M",
20
+ #"EH" => "YDDD", # Last Digit of Year and Julian Date Expressed in Format YDDD
21
+ "KA" => "%y%m%d",
22
+ "MD" => "%m%d",
23
+ "MM" => "%m",
24
+ #"TC" => "DDD", # Julian Date Expressed in Format DDD
25
+ "TM" => "%H%M",
26
+ "TQ" => "%m%y",
27
+ "TR" => "%d%m%y%H%M",
28
+ "TS" => "%H%M%S",
29
+ "TT" => "%m%d%y",
30
+ #"TU" => "YYDDD",
31
+ #"UN" => "", # Unstructured
32
+ "YM" => "%y%m",
33
+ "YY" => "%Y",
34
+ "RTS" => "%Y%m%d%H%M%S"}
35
+
36
+ DATE_FORMAT_RANGE =
37
+ {"DA" => ["%d", "%d"],
38
+ "DDT" => ["%Y%m%d", "%Y%m%d%H%M"],
39
+ "DTD" => ["%Y%m%d%H%M", "%Y%m%d"],
40
+ "DTS" => ["%Y%m%d%H%M%S", "%Y%m%d%H%M%S"],
41
+ "RD" => ["%m%d%Y", "%m%d%Y"],
42
+ "RD2" => ["%y", "%y"],
43
+ "RD4" => ["%Y", "%Y"],
44
+ "RD5" => ["%Y%m", "%Y%m"],
45
+ "RD6" => ["%y%m%d", "%y%m%d"],
46
+ "RD8" => ["%Y%m%d", "%Y%m%d"],
47
+ "RDM" => ["%y%m%d", "%m%d"],
48
+ "RDT" => ["%Y%m%d%H%M", "%Y%m%d%H%M"],
49
+ "RMD" => ["%m%d", "%m%d"],
50
+ "RMY" => ["%y%m", "%y%m"],
51
+ "RTM" => ["%H%M", "%H%M"]}
52
+ #"YMM" => ["CCYYMMM", "MMM"]
53
+
54
+ def companion
55
+ StringVal
56
+ end
57
+
58
+ # (see AN.strftime)
59
+ # def strftime(format, value)
60
+ # AN.strftime(format, value)
61
+ # end
62
+
63
+ # (see AN.stpftime)
64
+ # def strptime(format, value)
65
+ # AN.strptime(format, value)
66
+ # end
67
+ end
68
+
69
+ class << AN
70
+ # Format date (Date), date time (Time), or a range of either into a
71
+ # String, according to the given format specifier.
72
+ #
73
+ # See {AN::DATE_FORMAT_SINGLE} and {AN::DATE_FORMAT_RANGE} for a list
74
+ # of recognized format specifiers.
75
+ #
76
+ # @return [String]
77
+ def strftime(format, value)
78
+ if AN::DATE_FORMAT_RANGE.defined_at?(format)
79
+ unless value.kind_of?(Range) and
80
+ value.end.respond_to?(:strftime) and
81
+ value.begin.respond_to?(:strftime)
82
+ raise TypeError,
83
+ "expected a Range (#strftime..#strftime) but got #{value.inspect}"
84
+ end
85
+
86
+ f, g = AN::DATE_FORMAT_RANGE.at(format)
87
+ a, b = value.begin.strftime(f), value.end.strftime(g)
88
+ "#{a}-#{b}"
89
+ elsif AN::DATE_FORMAT_SINGLE.defined_at?(format)
90
+ unless value.respond_to?(:strftime)
91
+ raise TypeError,
92
+ "expected value to respond to #strftime, but got #{value.inspect}"
93
+ end
94
+
95
+ value.strftime(AN::DATE_FORMAT_SINGLE.at(format))
96
+
97
+ else
98
+ raise ArgumentError,
99
+ "unrecognized format specifier #{format.inspect}"
100
+ end
101
+ end
102
+
103
+ # Parse the string into a date (Date), date time (Time), or a range
104
+ # of either according to the given format specifier.
105
+ #
106
+ # See {AN::DATE_FORMAT_SINGLE} and {AN::DATE_FORMAT_RANGE} for a list
107
+ # of recognized format specifiers.
108
+ #
109
+ # @return [Time | Range<Time>]
110
+ def strptime(format, value)
111
+ if AN::DATE_FORMAT_RANGE.defined_at?(format)
112
+ f, g = AN::DATE_FORMAT_RANGE.at(format)
113
+ a, b = value.split("-", 2)
114
+
115
+ unless value =~ /^[^-]+-[^-]+$/
116
+ raise TypeError,
117
+ "expected a String with format #{f}-#{g}, but got #{value.inspect}"
118
+ end
119
+
120
+ Time.strptime("#{a} Z", "#{f} %z") .. Time.strptime("#{b} Z", "#{g} %z")
121
+ elsif AN::DATE_FORMAT_SINGLE.defined_at?(format)
122
+ Time.strptime("#{value} Z", "#{AN::DATE_FORMAT_SINGLE.at(format)} %z")
123
+ else
124
+ raise ArgumentError,
125
+ "unrecognized format specifier #{format.inspect}"
126
+ end
127
+ end
128
+ end
129
+
130
+ #
131
+ # @see X222.pdf B.1.1.3.1.4 String
132
+ #
133
+ class StringVal < Values::SimpleElementVal
134
+ def string?
135
+ true
136
+ end
137
+
138
+ def too_long?
139
+ false
140
+ end
141
+
142
+ def too_short?
143
+ false
144
+ end
145
+
146
+ class Invalid < StringVal
147
+ # @return [Object]
148
+ attr_reader :value
149
+
150
+ def initialize(value, usage, position)
151
+ @value = value
152
+ super(usage, position)
153
+ end
154
+
155
+ def valid?
156
+ false
157
+ end
158
+
159
+ def empty?
160
+ false
161
+ end
162
+
163
+ # @return [Invalid]
164
+ def map
165
+ self
166
+ end
167
+
168
+ # @return [String]
169
+ # :nocov:
170
+ def inspect
171
+ id = definition.bind do |d|
172
+ "[#{"% 5s" % d.id}: #{d.name}]".bind do |s|
173
+ if usage.forbidden?
174
+ ansi.forbidden(s)
175
+ elsif usage.required?
176
+ ansi.required(s)
177
+ else
178
+ ansi.optional(s)
179
+ end
180
+ end
181
+ end
182
+
183
+ ansi.element("AN.invalid#{id}") + "(#{ansi.invalid(@value.inspect)})"
184
+ end
185
+ # :nocov:
186
+
187
+ # @return [String]
188
+ def to_s
189
+ ""
190
+ end
191
+
192
+ # @return [String]
193
+ def to_x12(truncate = true)
194
+ ""
195
+ end
196
+
197
+ # @return [Boolean]
198
+ def ==(other)
199
+ eql?(other)
200
+ end
201
+
202
+ # @return [Invalid]
203
+ def copy(changes = {})
204
+ self
205
+ end
206
+ end
207
+
208
+ class Valid < StringVal
209
+ include Comparable
210
+
211
+ def_delegators :value, :to_d, :to_s, :to_f, :to_c, :to_r, :to_sym,
212
+ :to_str, :hex, :oct, :ord, :sum, :length, :count, :index, :rindex,
213
+ :lines, :bytes, :chars, :each, :upto, :split, :scan, :unpack, :=~,
214
+ :match, :partition, :rpatition, :encoding, :valid_enocding?, :at,
215
+ :empty?, :blank?
216
+
217
+ extend Operators::Wrappers
218
+ wrappers :%, :+, :*, :slice, :take, :drop, :[], :capitalize,
219
+ :center, :ljust, :rjust, :chomp, :delete, :tr, :tr_s,
220
+ :sub, :gsub, :encode, :force_encoding, :squeeze
221
+
222
+ extend Operators::Unary
223
+ unary_operators :chr, :chop, :upcase, :downcase, :strip,
224
+ :lstrip, :rstrip, :dump, :succ, :next, :reverse, :swapcase
225
+
226
+ extend Operators::Relational
227
+ relational_operators :<=>, :start_with?, :end_with?,
228
+ :include?, :casecmp, :coerce => :to_str
229
+
230
+ def ==(other)
231
+ other = StringVal.value(other, usage, position)
232
+ other.valid? and other.value == value
233
+ end
234
+
235
+ # @return [StringVal]
236
+ def copy(changes = {})
237
+ StringVal.value \
238
+ changes.fetch(:value, value),
239
+ changes.fetch(:usage, usage),
240
+ changes.fetch(:position, position)
241
+ end
242
+
243
+ def coerce(other)
244
+ return StringVal.value(other, usage, position), self
245
+ end
246
+
247
+ def valid?
248
+ true
249
+ end
250
+
251
+ # @return [StringVal]
252
+ def map
253
+ StringVal.value(yield(value), usage, position)
254
+ end
255
+ end
256
+
257
+ class Empty < Valid
258
+ # @return [String]
259
+ def value
260
+ ""
261
+ end
262
+
263
+ # @return [String]
264
+ # :nocov:
265
+ def inspect
266
+ id = definition.bind do |d|
267
+ "[#{"% 5s" % d.id}: #{d.name}]".bind do |s|
268
+ if usage.forbidden?
269
+ ansi.forbidden(s)
270
+ elsif usage.required?
271
+ ansi.required(s)
272
+ else
273
+ ansi.optional(s)
274
+ end
275
+ end
276
+ end
277
+
278
+ ansi.element("AN.empty#{id}")
279
+ end
280
+ # :nocov:
281
+
282
+ # @return [String]
283
+ def to_x12(truncate = true)
284
+ ""
285
+ end
286
+
287
+ def to_date(format)
288
+ nil
289
+ end
290
+ end
291
+
292
+ class NonEmpty < Valid
293
+ # @return [String]
294
+ attr_reader :value
295
+
296
+ def initialize(string, usage, position)
297
+ @value = string
298
+ super(usage, position)
299
+ end
300
+
301
+ def too_long?
302
+ @value.lstrip.length > definition.max_length
303
+ end
304
+
305
+ def too_short?
306
+ @value.lstrip.length < definition.min_length
307
+ end
308
+
309
+ # @return [String]
310
+ def to_x12(truncate = true)
311
+ x12 = @value.ljust(definition.min_length, " ")
312
+ truncate ? x12.take(definition.max_length) : x12
313
+ end
314
+
315
+ # @return [String]
316
+ # :nocov:
317
+ def inspect
318
+ id = definition.bind do |d|
319
+ "[#{"% 5s" % d.id}: #{d.name}]".bind do |s|
320
+ if usage.forbidden?
321
+ ansi.forbidden(s)
322
+ elsif usage.required?
323
+ ansi.required(s)
324
+ else
325
+ ansi.optional(s)
326
+ end
327
+ end
328
+ end
329
+
330
+ ansi.element("AN.value#{id}") + "(#{@value})"
331
+ end
332
+ # :nocov:
333
+
334
+ # (see AN.stpftime)
335
+ def to_date(format)
336
+ AN.strptime(format, @value)
337
+ end
338
+ end
339
+ end
340
+
341
+ class << StringVal
342
+ # @group Constructors
343
+ ###################################################################
344
+
345
+ # @return [StringVal]
346
+ def empty(usage, position)
347
+ self::Empty.new(usage, position)
348
+ end
349
+
350
+ # @return [StringVal]
351
+ def value(object, usage, position)
352
+ if object.is_a?(StringVal)
353
+ object#.copy(:usage => usage, :position => position)
354
+ elsif object.blank?
355
+ self::Empty.new(usage, position)
356
+ elsif object.kind_of?(Date) or object.kind_of?(Time)
357
+ self::Invalid.new(object, usage, position)
358
+ else
359
+ self::NonEmpty.new(object.to_s.rstrip, usage, position)
360
+ end
361
+ rescue
362
+ self::Invalid.new(object, usage, position)
363
+ end
364
+
365
+ # Because this constructor is only called by a programmer (and not
366
+ # when the parser is reading a file), we will throw an exception
367
+ # rather than quietly returning an {StringVal::Invalid}.
368
+ #
369
+ # @return [StringVal]
370
+ # def from_date(format, value, usage, position)
371
+ # self::NonEmpty.new(AN.strftime(format, value), usage, position)
372
+ # end
373
+
374
+ # @endgroup
375
+ ###################################################################
376
+ end
377
+
378
+ # Prevent direct instantiation of abstract class StringVal
379
+ StringVal.eigenclass.send(:protected, :new)
380
+ StringVal::Empty.eigenclass.send(:public, :new)
381
+ StringVal::Invalid.eigenclass.send(:public, :new)
382
+ StringVal::NonEmpty.eigenclass.send(:public, :new)
383
+ end
384
+ end
385
+ end
386
+ end