stupidedi 1.1.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 (500) hide show
  1. data/README.md +215 -0
  2. data/Rakefile +108 -0
  3. data/bin/edi-ed +71 -0
  4. data/bin/edi-pp +81 -0
  5. data/doc/Defining.md +0 -0
  6. data/doc/Generating.md +321 -0
  7. data/doc/LICENSE.md +0 -0
  8. data/doc/Navigating.md +645 -0
  9. data/doc/Parsing.md +0 -0
  10. data/doc/Serializing.md +7 -0
  11. data/doc/Tokenizing.md +0 -0
  12. data/doc/Validating.md +0 -0
  13. data/doc/design/Parser.md +0 -0
  14. data/doc/design/Reader.md +0 -0
  15. data/lib/ruby/array.rb +164 -0
  16. data/lib/ruby/blank.rb +67 -0
  17. data/lib/ruby/enumerable.rb +35 -0
  18. data/lib/ruby/exception.rb +33 -0
  19. data/lib/ruby/hash.rb +4 -0
  20. data/lib/ruby/instance_exec.rb +26 -0
  21. data/lib/ruby/module.rb +79 -0
  22. data/lib/ruby/object.rb +63 -0
  23. data/lib/ruby/string.rb +73 -0
  24. data/lib/ruby/symbol.rb +24 -0
  25. data/lib/ruby/to_d.rb +81 -0
  26. data/lib/ruby/to_date.rb +33 -0
  27. data/lib/ruby/to_time.rb +24 -0
  28. data/lib/ruby/try.rb +43 -0
  29. data/lib/stupidedi/blank_slate.rb +11 -0
  30. data/lib/stupidedi/builder/builder_dsl.rb +281 -0
  31. data/lib/stupidedi/builder/constraint_table.rb +418 -0
  32. data/lib/stupidedi/builder/generation.rb +112 -0
  33. data/lib/stupidedi/builder/instruction.rb +102 -0
  34. data/lib/stupidedi/builder/instruction_table.rb +204 -0
  35. data/lib/stupidedi/builder/navigation.rb +655 -0
  36. data/lib/stupidedi/builder/state_machine.rb +55 -0
  37. data/lib/stupidedi/builder/states/abstract_state.rb +332 -0
  38. data/lib/stupidedi/builder/states/failure_state.rb +69 -0
  39. data/lib/stupidedi/builder/states/functional_group_state.rb +97 -0
  40. data/lib/stupidedi/builder/states/initial_state.rb +63 -0
  41. data/lib/stupidedi/builder/states/interchange_state.rb +94 -0
  42. data/lib/stupidedi/builder/states/loop_state.rb +79 -0
  43. data/lib/stupidedi/builder/states/table_state.rb +96 -0
  44. data/lib/stupidedi/builder/states/transaction_set_state.rb +112 -0
  45. data/lib/stupidedi/builder/states/transmission_state.rb +59 -0
  46. data/lib/stupidedi/builder/tokenization.rb +196 -0
  47. data/lib/stupidedi/builder.rb +23 -0
  48. data/lib/stupidedi/color.rb +93 -0
  49. data/lib/stupidedi/config/code_list_config.rb +42 -0
  50. data/lib/stupidedi/config/editor_config.rb +51 -0
  51. data/lib/stupidedi/config/functional_group_config.rb +62 -0
  52. data/lib/stupidedi/config/interchange_config.rb +79 -0
  53. data/lib/stupidedi/config/transaction_set_config.rb +91 -0
  54. data/lib/stupidedi/config.rb +101 -0
  55. data/lib/stupidedi/editor/00501.rb +341 -0
  56. data/lib/stupidedi/editor/005010/N2.rb +0 -0
  57. data/lib/stupidedi/editor/005010/N3.rb +0 -0
  58. data/lib/stupidedi/editor/005010/N4.rb +63 -0
  59. data/lib/stupidedi/editor/005010/NM1.rb +0 -0
  60. data/lib/stupidedi/editor/005010.rb +469 -0
  61. data/lib/stupidedi/editor/X222-HC837.rb +195 -0
  62. data/lib/stupidedi/editor/abstract_ed.rb +36 -0
  63. data/lib/stupidedi/editor/claim_ack.rb +9 -0
  64. data/lib/stupidedi/editor/implementation_ack.rb +213 -0
  65. data/lib/stupidedi/editor/interchange_ack.rb +9 -0
  66. data/lib/stupidedi/editor/result.rb +100 -0
  67. data/lib/stupidedi/editor/result_set.rb +69 -0
  68. data/lib/stupidedi/editor/transaction_set_ed.rb +275 -0
  69. data/lib/stupidedi/editor/transmission_ed.rb +90 -0
  70. data/lib/stupidedi/editor.rb +37 -0
  71. data/lib/stupidedi/either.rb +287 -0
  72. data/lib/stupidedi/exceptions/invalid_element_error.rb +8 -0
  73. data/lib/stupidedi/exceptions/invalid_schema_error.rb +8 -0
  74. data/lib/stupidedi/exceptions/output_error.rb +8 -0
  75. data/lib/stupidedi/exceptions/parse_error.rb +8 -0
  76. data/lib/stupidedi/exceptions/stupidedi_error.rb +8 -0
  77. data/lib/stupidedi/exceptions/tokenize_error.rb +8 -0
  78. data/lib/stupidedi/exceptions/zipper_error.rb +8 -0
  79. data/lib/stupidedi/exceptions.rb +11 -0
  80. data/lib/stupidedi/guides/005010/X214-HN277.rb +409 -0
  81. data/lib/stupidedi/guides/005010/X221-HP835.rb +613 -0
  82. data/lib/stupidedi/guides/005010/X221A1-HP835.rb +613 -0
  83. data/lib/stupidedi/guides/005010/X222-HC837P.rb +2291 -0
  84. data/lib/stupidedi/guides/005010/X222A1-HC837P.rb +2297 -0
  85. data/lib/stupidedi/guides/005010/X231-FA999.rb +123 -0
  86. data/lib/stupidedi/guides/005010/X231A1-FA999.rb +119 -0
  87. data/lib/stupidedi/guides/005010/element_reqs.rb +38 -0
  88. data/lib/stupidedi/guides/005010/guide_builder.rb +180 -0
  89. data/lib/stupidedi/guides/005010/segment_reqs.rb +32 -0
  90. data/lib/stupidedi/guides/005010.rb +64 -0
  91. data/lib/stupidedi/guides.rb +5 -0
  92. data/lib/stupidedi/inspect.rb +26 -0
  93. data/lib/stupidedi/reader/input/abstract_input.rb +133 -0
  94. data/lib/stupidedi/reader/input/delegated_input.rb +111 -0
  95. data/lib/stupidedi/reader/input/file_input.rb +155 -0
  96. data/lib/stupidedi/reader/input.rb +30 -0
  97. data/lib/stupidedi/reader/position.rb +69 -0
  98. data/lib/stupidedi/reader/result.rb +168 -0
  99. data/lib/stupidedi/reader/segment_dict.rb +175 -0
  100. data/lib/stupidedi/reader/separators.rb +85 -0
  101. data/lib/stupidedi/reader/stream_reader.rb +172 -0
  102. data/lib/stupidedi/reader/token_reader.rb +466 -0
  103. data/lib/stupidedi/reader/tokens/component_element_tok.rb +56 -0
  104. data/lib/stupidedi/reader/tokens/composite_element_tok.rb +64 -0
  105. data/lib/stupidedi/reader/tokens/repeated_element_tok.rb +64 -0
  106. data/lib/stupidedi/reader/tokens/segment_tok.rb +51 -0
  107. data/lib/stupidedi/reader/tokens/simple_element_tok.rb +63 -0
  108. data/lib/stupidedi/reader.rb +121 -0
  109. data/lib/stupidedi/schema/abstract_def.rb +74 -0
  110. data/lib/stupidedi/schema/abstract_use.rb +73 -0
  111. data/lib/stupidedi/schema/code_list.rb +94 -0
  112. data/lib/stupidedi/schema/element_def.rb +173 -0
  113. data/lib/stupidedi/schema/element_req.rb +56 -0
  114. data/lib/stupidedi/schema/element_use.rb +251 -0
  115. data/lib/stupidedi/schema/functional_group_def.rb +114 -0
  116. data/lib/stupidedi/schema/interchange_def.rb +93 -0
  117. data/lib/stupidedi/schema/loop_def.rb +152 -0
  118. data/lib/stupidedi/schema/repeat_count.rb +85 -0
  119. data/lib/stupidedi/schema/segment_def.rb +108 -0
  120. data/lib/stupidedi/schema/segment_req.rb +43 -0
  121. data/lib/stupidedi/schema/segment_use.rb +98 -0
  122. data/lib/stupidedi/schema/syntax_note.rb +63 -0
  123. data/lib/stupidedi/schema/table_def.rb +139 -0
  124. data/lib/stupidedi/schema/transaction_set_def.rb +88 -0
  125. data/lib/stupidedi/schema.rb +28 -0
  126. data/lib/stupidedi/sets/absolute_set.rb +297 -0
  127. data/lib/stupidedi/sets/abstract_set.rb +174 -0
  128. data/lib/stupidedi/sets/null_set.rb +125 -0
  129. data/lib/stupidedi/sets/relative_complement.rb +137 -0
  130. data/lib/stupidedi/sets/relative_set.rb +269 -0
  131. data/lib/stupidedi/sets/universal_set.rb +104 -0
  132. data/lib/stupidedi/sets.rb +57 -0
  133. data/lib/stupidedi/tail_call.rb +109 -0
  134. data/lib/stupidedi/thread_local.rb +174 -0
  135. data/lib/stupidedi/values/abstract_element_val.rb +19 -0
  136. data/lib/stupidedi/values/abstract_val.rb +130 -0
  137. data/lib/stupidedi/values/composite_element_val.rb +95 -0
  138. data/lib/stupidedi/values/functional_group_val.rb +102 -0
  139. data/lib/stupidedi/values/interchange_val.rb +86 -0
  140. data/lib/stupidedi/values/invalid_envelope_val.rb +61 -0
  141. data/lib/stupidedi/values/invalid_segment_val.rb +78 -0
  142. data/lib/stupidedi/values/loop_val.rb +70 -0
  143. data/lib/stupidedi/values/repeated_element_val.rb +105 -0
  144. data/lib/stupidedi/values/segment_val.rb +104 -0
  145. data/lib/stupidedi/values/segment_val_group.rb +20 -0
  146. data/lib/stupidedi/values/simple_element_val.rb +80 -0
  147. data/lib/stupidedi/values/table_val.rb +66 -0
  148. data/lib/stupidedi/values/transaction_set_val.rb +66 -0
  149. data/lib/stupidedi/values/transmission_val.rb +52 -0
  150. data/lib/stupidedi/values.rb +21 -0
  151. data/lib/stupidedi/version.rb +3 -0
  152. data/lib/stupidedi/versions/functional_groups/004010/element_defs.rb +54 -0
  153. data/lib/stupidedi/versions/functional_groups/004010/element_reqs.rb +18 -0
  154. data/lib/stupidedi/versions/functional_groups/004010/element_types/date_val.rb +527 -0
  155. data/lib/stupidedi/versions/functional_groups/004010/element_types/fixnum_val.rb +335 -0
  156. data/lib/stupidedi/versions/functional_groups/004010/element_types/float_val.rb +299 -0
  157. data/lib/stupidedi/versions/functional_groups/004010/element_types/identifier_val.rb +287 -0
  158. data/lib/stupidedi/versions/functional_groups/004010/element_types/string_val.rb +338 -0
  159. data/lib/stupidedi/versions/functional_groups/004010/element_types/time_val.rb +309 -0
  160. data/lib/stupidedi/versions/functional_groups/004010/element_types.rb +124 -0
  161. data/lib/stupidedi/versions/functional_groups/004010/functional_group_def.rb +30 -0
  162. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GE.rb +20 -0
  163. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GS.rb +27 -0
  164. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/SE.rb +20 -0
  165. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/ST.rb +20 -0
  166. data/lib/stupidedi/versions/functional_groups/004010/segment_defs.rb +23 -0
  167. data/lib/stupidedi/versions/functional_groups/004010/segment_reqs.rb +18 -0
  168. data/lib/stupidedi/versions/functional_groups/004010/syntax_notes.rb +174 -0
  169. data/lib/stupidedi/versions/functional_groups/004010.rb +38 -0
  170. data/lib/stupidedi/versions/functional_groups/005010/element_defs.rb +1405 -0
  171. data/lib/stupidedi/versions/functional_groups/005010/element_reqs.rb +18 -0
  172. data/lib/stupidedi/versions/functional_groups/005010/element_types/date_val.rb +577 -0
  173. data/lib/stupidedi/versions/functional_groups/005010/element_types/fixnum_val.rb +322 -0
  174. data/lib/stupidedi/versions/functional_groups/005010/element_types/float_val.rb +354 -0
  175. data/lib/stupidedi/versions/functional_groups/005010/element_types/identifier_val.rb +368 -0
  176. data/lib/stupidedi/versions/functional_groups/005010/element_types/operators.rb +117 -0
  177. data/lib/stupidedi/versions/functional_groups/005010/element_types/string_val.rb +398 -0
  178. data/lib/stupidedi/versions/functional_groups/005010/element_types/time_val.rb +327 -0
  179. data/lib/stupidedi/versions/functional_groups/005010/element_types.rb +132 -0
  180. data/lib/stupidedi/versions/functional_groups/005010/functional_group_def.rb +30 -0
  181. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK1.rb +21 -0
  182. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK2.rb +21 -0
  183. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK9.rb +28 -0
  184. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AMT.rb +21 -0
  185. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BHT.rb +24 -0
  186. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BPR.rb +49 -0
  187. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CAS.rb +56 -0
  188. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CL1.rb +22 -0
  189. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLM.rb +41 -0
  190. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLP.rb +34 -0
  191. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CN1.rb +24 -0
  192. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR1.rb +32 -0
  193. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR2.rb +35 -0
  194. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR3.rb +25 -0
  195. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CRC.rb +26 -0
  196. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTP.rb +36 -0
  197. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTX.rb +24 -0
  198. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CUR.rb +57 -0
  199. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DMG.rb +34 -0
  200. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN1.rb +22 -0
  201. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN2.rb +24 -0
  202. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTM.rb +24 -0
  203. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTP.rb +21 -0
  204. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/FRM.rb +25 -0
  205. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GE.rb +20 -0
  206. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GS.rb +27 -0
  207. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HCP.rb +39 -0
  208. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HI.rb +31 -0
  209. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HL.rb +22 -0
  210. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK3.rb +22 -0
  211. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK4.rb +22 -0
  212. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK5.rb +24 -0
  213. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/K3.rb +21 -0
  214. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LIN.rb +69 -0
  215. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LQ.rb +22 -0
  216. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LX.rb +19 -0
  217. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MEA.rb +39 -0
  218. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MIA.rb +45 -0
  219. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MOA.rb +28 -0
  220. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N1.rb +24 -0
  221. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N2.rb +20 -0
  222. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N3.rb +20 -0
  223. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N4.rb +30 -0
  224. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NM1.rb +35 -0
  225. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NTE.rb +20 -0
  226. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/OI.rb +24 -0
  227. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PAT.rb +31 -0
  228. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PER.rb +32 -0
  229. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PLB.rb +40 -0
  230. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PRV.rb +26 -0
  231. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PS1.rb +21 -0
  232. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PWK.rb +30 -0
  233. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/QTY.rb +25 -0
  234. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/RDM.rb +23 -0
  235. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/REF.rb +23 -0
  236. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SBR.rb +28 -0
  237. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SE.rb +20 -0
  238. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/ST.rb +21 -0
  239. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/STC.rb +30 -0
  240. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV1.rb +44 -0
  241. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV2.rb +29 -0
  242. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV3.rb +30 -0
  243. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV5.rb +29 -0
  244. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVC.rb +26 -0
  245. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVD.rb +24 -0
  246. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TOO.rb +21 -0
  247. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TRN.rb +22 -0
  248. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS2.rb +40 -0
  249. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS3.rb +45 -0
  250. data/lib/stupidedi/versions/functional_groups/005010/segment_defs.rb +227 -0
  251. data/lib/stupidedi/versions/functional_groups/005010/segment_reqs.rb +18 -0
  252. data/lib/stupidedi/versions/functional_groups/005010/syntax_notes.rb +165 -0
  253. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/FA999.rb +38 -0
  254. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HB271.rb +85 -0
  255. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HC837.rb +163 -0
  256. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HI278.rb +64 -0
  257. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HN277.rb +74 -0
  258. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HP835.rb +68 -0
  259. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HR276.rb +57 -0
  260. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HS270.rb +53 -0
  261. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/RA820.rb +240 -0
  262. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs.rb +68 -0
  263. data/lib/stupidedi/versions/functional_groups/005010.rb +38 -0
  264. data/lib/stupidedi/versions/functional_groups.rb +8 -0
  265. data/lib/stupidedi/versions/interchanges/00401/element_defs.rb +224 -0
  266. data/lib/stupidedi/versions/interchanges/00401/interchange_def.rb +45 -0
  267. data/lib/stupidedi/versions/interchanges/00401/segment_defs/IEA.rb +20 -0
  268. data/lib/stupidedi/versions/interchanges/00401/segment_defs/ISA.rb +34 -0
  269. data/lib/stupidedi/versions/interchanges/00401/segment_defs/TA1.rb +23 -0
  270. data/lib/stupidedi/versions/interchanges/00401/segment_defs.rb +28 -0
  271. data/lib/stupidedi/versions/interchanges/00401.rb +23 -0
  272. data/lib/stupidedi/versions/interchanges/00501/element_defs.rb +269 -0
  273. data/lib/stupidedi/versions/interchanges/00501/interchange_def.rb +47 -0
  274. data/lib/stupidedi/versions/interchanges/00501/segment_defs/IEA.rb +20 -0
  275. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISA.rb +34 -0
  276. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISB.rb +18 -0
  277. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISE.rb +18 -0
  278. data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA1.rb +23 -0
  279. data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA3.rb +18 -0
  280. data/lib/stupidedi/versions/interchanges/00501/segment_defs.rb +37 -0
  281. data/lib/stupidedi/versions/interchanges/00501.rb +23 -0
  282. data/lib/stupidedi/versions/interchanges.rb +8 -0
  283. data/lib/stupidedi/versions.rb +6 -0
  284. data/lib/stupidedi/writer/claredi.rb +142 -0
  285. data/lib/stupidedi/writer/default.rb +124 -0
  286. data/lib/stupidedi/writer.rb +6 -0
  287. data/lib/stupidedi/zipper/abstract_cursor.rb +351 -0
  288. data/lib/stupidedi/zipper/dangling_cursor.rb +103 -0
  289. data/lib/stupidedi/zipper/edited_cursor.rb +157 -0
  290. data/lib/stupidedi/zipper/memoized_cursor.rb +131 -0
  291. data/lib/stupidedi/zipper/path.rb +124 -0
  292. data/lib/stupidedi/zipper/root_cursor.rb +120 -0
  293. data/lib/stupidedi/zipper.rb +25 -0
  294. data/lib/stupidedi.rb +66 -0
  295. data/spec/examples/integration/generating.example +551 -0
  296. data/spec/examples/integration/navigating.example +214 -0
  297. data/spec/examples/integration/parsing.example +445 -0
  298. data/spec/examples/ruby/array.example +476 -0
  299. data/spec/examples/ruby/blank.example +62 -0
  300. data/spec/examples/ruby/count.example +68 -0
  301. data/spec/examples/ruby/object.example +99 -0
  302. data/spec/examples/ruby/string.example +111 -0
  303. data/spec/examples/ruby/symbol.example +117 -0
  304. data/spec/examples/ruby/to_d.example +90 -0
  305. data/spec/examples/ruby/try.example +50 -0
  306. data/spec/examples/stupidedi/either.example +375 -0
  307. data/spec/examples/stupidedi/reader/failure.example +68 -0
  308. data/spec/examples/stupidedi/reader/input/delegated_input.example +292 -0
  309. data/spec/examples/stupidedi/reader/separators.example +73 -0
  310. data/spec/examples/stupidedi/reader/stream_reader.example +48 -0
  311. data/spec/examples/stupidedi/reader/success.example +34 -0
  312. data/spec/examples/stupidedi/reader/token_reader.example +775 -0
  313. data/spec/examples/stupidedi/reader.example +168 -0
  314. data/spec/examples/stupidedi/sets/absolute_set.example +1577 -0
  315. data/spec/examples/stupidedi/sets/null_set.example +2 -0
  316. data/spec/examples/stupidedi/sets/relative_set.example +2 -0
  317. data/spec/examples/stupidedi/sets/universal_set.example +1 -0
  318. data/spec/examples/stupidedi/versions/005010/element_types/an.example +201 -0
  319. data/spec/examples/stupidedi/versions/005010/element_types/dt.example +258 -0
  320. data/spec/examples/stupidedi/versions/005010/element_types/id.example +192 -0
  321. data/spec/examples/stupidedi/versions/005010/element_types/nn.example +177 -0
  322. data/spec/examples/stupidedi/versions/005010/element_types/r.example +178 -0
  323. data/spec/examples/stupidedi/versions/005010/element_types/tm.example +2 -0
  324. data/spec/examples/stupidedi/zipper/abstract_cursor.example +417 -0
  325. data/spec/examples/stupidedi/zipper.example +9 -0
  326. data/spec/fixtures/X186-AG824/1-bad.txt +21 -0
  327. data/spec/fixtures/X186-AG824/1-good.txt +17 -0
  328. data/spec/fixtures/X186-AG824/2-bad.txt +26 -0
  329. data/spec/fixtures/X186-AG824/2-good.txt +21 -0
  330. data/spec/fixtures/X186-AG824/3-bad.txt +87 -0
  331. data/spec/fixtures/X186-AG824/3-good.txt +61 -0
  332. data/spec/fixtures/X212-HN277/1-bad.txt +54 -0
  333. data/spec/fixtures/X212-HN277/1-good.txt +46 -0
  334. data/spec/fixtures/X212-HN277/2-bad.txt +37 -0
  335. data/spec/fixtures/X212-HN277/2-good.txt +29 -0
  336. data/spec/fixtures/X212-HN277/3-bad.txt +22 -0
  337. data/spec/fixtures/X212-HN277/3-good.txt +17 -0
  338. data/spec/fixtures/X212-HN277/4-bad.txt +30 -0
  339. data/spec/fixtures/X212-HN277/4-good.txt +24 -0
  340. data/spec/fixtures/X212-HR276/1-bad.txt +53 -0
  341. data/spec/fixtures/X212-HR276/1-good.txt +46 -0
  342. data/spec/fixtures/X212-HR276/2-bad.txt +45 -0
  343. data/spec/fixtures/X212-HR276/2-good.txt +38 -0
  344. data/spec/fixtures/X212-HR276/3-bad.txt +32 -0
  345. data/spec/fixtures/X212-HR276/3-good.txt +26 -0
  346. data/spec/fixtures/X212-HR276/4-bad.txt +32 -0
  347. data/spec/fixtures/X212-HR276/4-good.txt +26 -0
  348. data/spec/fixtures/X214-HN277/1-bad.txt +58 -0
  349. data/spec/fixtures/X214-HN277/1-good.txt +47 -0
  350. data/spec/fixtures/X214-HN277/2-bad.txt +34 -0
  351. data/spec/fixtures/X214-HN277/2-good.txt +22 -0
  352. data/spec/fixtures/X214-HN277/3-bad.txt +64 -0
  353. data/spec/fixtures/X214-HN277/3-good.txt +54 -0
  354. data/spec/fixtures/X214-HN277/4-bad.txt +77 -0
  355. data/spec/fixtures/X214-HN277/4-good.txt +63 -0
  356. data/spec/fixtures/X216-HI278/1-bad.txt +42 -0
  357. data/spec/fixtures/X216-HI278/1-good.txt +27 -0
  358. data/spec/fixtures/X216-HI278/2-bad.txt +43 -0
  359. data/spec/fixtures/X216-HI278/2-good.txt +29 -0
  360. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1.txt +24 -0
  361. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1_Clean.txt +20 -0
  362. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2.txt +46 -0
  363. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2_Clean.txt +30 -0
  364. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3.txt +38 -0
  365. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3_Clean.txt +24 -0
  366. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a.txt +39 -0
  367. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a_Clean.txt +24 -0
  368. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b.txt +43 -0
  369. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b_Clean.txt +25 -0
  370. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5.txt +63 -0
  371. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5_Clean.txt +41 -0
  372. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6.txt +36 -0
  373. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6_Clean.txt +20 -0
  374. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r.txt +34 -0
  375. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r_Clean.txt +23 -0
  376. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r.txt +46 -0
  377. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r_Clean.txt +31 -0
  378. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r.txt +44 -0
  379. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r_Clean.txt +26 -0
  380. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4ar_Clean.txt +28 -0
  381. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4br_Clean.txt +35 -0
  382. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r.txt +60 -0
  383. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r_Clean.txt +42 -0
  384. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r.txt +40 -0
  385. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r_Clean.txt +24 -0
  386. data/spec/fixtures/X218-RA820/1-bad.txt +31 -0
  387. data/spec/fixtures/X218-RA820/1-good.txt +25 -0
  388. data/spec/fixtures/X218-RA820/2-bad.txt +37 -0
  389. data/spec/fixtures/X218-RA820/2-good.txt +29 -0
  390. data/spec/fixtures/X218-RA820/3-bad.txt +29 -0
  391. data/spec/fixtures/X218-RA820/3-good.txt +23 -0
  392. data/spec/fixtures/X218-RA820/4-bad.txt +36 -0
  393. data/spec/fixtures/X218-RA820/4-good.txt +27 -0
  394. data/spec/fixtures/X220-BE834/1-bad.txt +35 -0
  395. data/spec/fixtures/X220-BE834/1-good.txt +29 -0
  396. data/spec/fixtures/X220-BE834/10-bad.txt +26 -0
  397. data/spec/fixtures/X220-BE834/10-good.txt +19 -0
  398. data/spec/fixtures/X220-BE834/2-bad.txt +31 -0
  399. data/spec/fixtures/X220-BE834/2-good.txt +23 -0
  400. data/spec/fixtures/X220-BE834/3-bad.txt +36 -0
  401. data/spec/fixtures/X220-BE834/3-good.txt +26 -0
  402. data/spec/fixtures/X220-BE834/4-bad.txt +27 -0
  403. data/spec/fixtures/X220-BE834/4-good.txt +21 -0
  404. data/spec/fixtures/X220-BE834/5-bad.txt +26 -0
  405. data/spec/fixtures/X220-BE834/5-good.txt +17 -0
  406. data/spec/fixtures/X220-BE834/6-bad.txt +25 -0
  407. data/spec/fixtures/X220-BE834/6-good.txt +20 -0
  408. data/spec/fixtures/X220-BE834/7-bad.txt +25 -0
  409. data/spec/fixtures/X220-BE834/7-good.txt +20 -0
  410. data/spec/fixtures/X220-BE834/8-bad.txt +25 -0
  411. data/spec/fixtures/X220-BE834/8-good.txt +20 -0
  412. data/spec/fixtures/X220-BE834/9-bad.txt +27 -0
  413. data/spec/fixtures/X220-BE834/9-good.txt +21 -0
  414. data/spec/fixtures/X221-HP835/1-bad.txt +58 -0
  415. data/spec/fixtures/X221-HP835/1-good.txt +40 -0
  416. data/spec/fixtures/X221-HP835/2-bad.txt +51 -0
  417. data/spec/fixtures/X221-HP835/2-good.txt +40 -0
  418. data/spec/fixtures/X221-HP835/3a-bad.txt +78 -0
  419. data/spec/fixtures/X221-HP835/3a-good.txt +49 -0
  420. data/spec/fixtures/X221-HP835/3b-bad.txt +60 -0
  421. data/spec/fixtures/X221-HP835/3b-good.txt +32 -0
  422. data/spec/fixtures/X221-HP835/3c-bad.txt +55 -0
  423. data/spec/fixtures/X221-HP835/3c-good.txt +34 -0
  424. data/spec/fixtures/X222-HC837/1-bad.txt +60 -0
  425. data/spec/fixtures/X222-HC837/1-good.txt +53 -0
  426. data/spec/fixtures/X222-HC837/10a-bad.txt +52 -0
  427. data/spec/fixtures/X222-HC837/10a-good.txt +40 -0
  428. data/spec/fixtures/X222-HC837/10b-bad.txt +99 -0
  429. data/spec/fixtures/X222-HC837/10b-good.txt +80 -0
  430. data/spec/fixtures/X222-HC837/10c-bad.txt +105 -0
  431. data/spec/fixtures/X222-HC837/10c-good.txt +80 -0
  432. data/spec/fixtures/X222-HC837/11-bad.txt +69 -0
  433. data/spec/fixtures/X222-HC837/11-good.txt +45 -0
  434. data/spec/fixtures/X222-HC837/12-bad.txt +73 -0
  435. data/spec/fixtures/X222-HC837/12-good.txt +51 -0
  436. data/spec/fixtures/X222-HC837/13-bad.txt +64 -0
  437. data/spec/fixtures/X222-HC837/13-good.txt +46 -0
  438. data/spec/fixtures/X222-HC837/3a-bad.txt +83 -0
  439. data/spec/fixtures/X222-HC837/3a-good.txt +59 -0
  440. data/spec/fixtures/X222-HC837/3b-bad.txt +97 -0
  441. data/spec/fixtures/X222-HC837/3b-good.txt +70 -0
  442. data/spec/fixtures/X222-HC837/3c-bad.txt +95 -0
  443. data/spec/fixtures/X222-HC837/3c-good.txt +74 -0
  444. data/spec/fixtures/X222-HC837/4-bad.txt +67 -0
  445. data/spec/fixtures/X222-HC837/4-good.txt +48 -0
  446. data/spec/fixtures/X222-HC837/5-bad.txt +73 -0
  447. data/spec/fixtures/X222-HC837/5-good.txt +60 -0
  448. data/spec/fixtures/X222-HC837/6-bad.txt +50 -0
  449. data/spec/fixtures/X222-HC837/6-good.txt +39 -0
  450. data/spec/fixtures/X222-HC837/7-bad.txt +93 -0
  451. data/spec/fixtures/X222-HC837/7-good.txt +78 -0
  452. data/spec/fixtures/X222-HC837/8-bad.txt +64 -0
  453. data/spec/fixtures/X222-HC837/8-good.txt +52 -0
  454. data/spec/fixtures/X222-HC837/9-bad.txt +56 -0
  455. data/spec/fixtures/X222-HC837/9-good.txt +38 -0
  456. data/spec/fixtures/X223-HC837/1-bad.txt +66 -0
  457. data/spec/fixtures/X223-HC837/1-good.txt +53 -0
  458. data/spec/fixtures/X223-HC837/2-bad.txt +69 -0
  459. data/spec/fixtures/X223-HC837/2-good.txt +60 -0
  460. data/spec/fixtures/X223-HC837/3-bad.txt +89 -0
  461. data/spec/fixtures/X223-HC837/3-good.txt +61 -0
  462. data/spec/fixtures/X223-HC837/4-bad.txt +60 -0
  463. data/spec/fixtures/X223-HC837/4-good.txt +40 -0
  464. data/spec/fixtures/X223-HC837/5-bad.txt +75 -0
  465. data/spec/fixtures/X223-HC837/5-good.txt +58 -0
  466. data/spec/fixtures/X224-HC837/1-bad.txt +54 -0
  467. data/spec/fixtures/X224-HC837/1-good.txt +44 -0
  468. data/spec/fixtures/X224-HC837/2a-bad.txt +52 -0
  469. data/spec/fixtures/X224-HC837/2a-good.txt +42 -0
  470. data/spec/fixtures/X224-HC837/2b-bad.txt +67 -0
  471. data/spec/fixtures/X224-HC837/2b-good.txt +52 -0
  472. data/spec/fixtures/X224-HC837/3-bad.txt +67 -0
  473. data/spec/fixtures/X224-HC837/3-good.txt +51 -0
  474. data/spec/fixtures/X224-HC837/4-bad.txt +49 -0
  475. data/spec/fixtures/X224-HC837/4-good.txt +40 -0
  476. data/spec/fixtures/X230-FA997/1-bad.txt +19 -0
  477. data/spec/fixtures/X230-FA997/1-good.txt +16 -0
  478. data/spec/fixtures/X231-FA999/1-bad.txt +20 -0
  479. data/spec/fixtures/X231-FA999/1-good.txt +20 -0
  480. data/spec/fixtures/X279-HB271/1-bad.txt +36 -0
  481. data/spec/fixtures/X279-HB271/1-good.txt +30 -0
  482. data/spec/fixtures/X279-HB271/2-bad.txt +22 -0
  483. data/spec/fixtures/X279-HB271/2-good.txt +16 -0
  484. data/spec/fixtures/X279-HB271/3-bad.txt +44 -0
  485. data/spec/fixtures/X279-HB271/3-good.txt +36 -0
  486. data/spec/fixtures/X279-HS270/1-bad.txt +29 -0
  487. data/spec/fixtures/X279-HS270/1-good.txt +23 -0
  488. data/spec/fixtures/X279-HS270/2-bad.txt +32 -0
  489. data/spec/fixtures/X279-HS270/2-good.txt +25 -0
  490. data/spec/spec_helper.rb +34 -0
  491. data/spec/support/fixtures.rb +26 -0
  492. data/spec/support/matchers/either_matchers.rb +26 -0
  493. data/spec/support/matchers/navigation_matchers.rb +247 -0
  494. data/spec/support/node.rb +41 -0
  495. data/spec/support/quickcheck/characters.rb +28 -0
  496. data/spec/support/quickcheck/property.rb +105 -0
  497. data/spec/support/quickcheck/serialized_edi.rb +399 -0
  498. data/spec/support/quickcheck.rb +302 -0
  499. data/spec/support/rcov.rb +34 -0
  500. metadata +577 -0
@@ -0,0 +1,54 @@
1
+ module Stupidedi
2
+ module Versions
3
+ module FunctionalGroups
4
+ module FortyTen
5
+ module ElementDefs
6
+
7
+ t = ElementTypes
8
+ r = ElementReqs
9
+ s = Schema
10
+
11
+ E28 = t::Nn.new(:E28 , "Group Control Number" , 1, 9, 0)
12
+
13
+ E96 = t::Nn.new(:E96 , "Number of Included Segments" , 1, 10, 0)
14
+ E97 = t::Nn.new(:E97 , "Number of Transaction Sets Included" , 1, 6, 0)
15
+
16
+ E124 = t::AN.new(:E124 , "Application Receiver's Code" , 2, 15)
17
+
18
+ E142 = t::AN.new(:E142 , "Application's Sender Code" , 2, 15)
19
+ E143 = t::ID.new(:E143 , "Transaction Set Identifier Number" , 3, 3,
20
+ s::CodeList.build(
21
+ "277" => "Health Care Information Status Notification",
22
+ "835" => "Health Care Claim Payment/Advice",
23
+ "837" => "Health Care Claim"))
24
+
25
+ E329 = t::ID.new(:E329 , "Transaction Set Control Number" , 4, 9)
26
+
27
+ E373 = t::DT.new(:E373 , "Date" , 8, 8)
28
+
29
+ E337 = t::TM.new(:E337 , "Time" , 4, 8)
30
+
31
+ E455 = t::ID.new(:E455 , "Responsible Agency Code" , 1, 2,
32
+ s::CodeList.build(
33
+ "X" => "Accredited Standards Committee X12"))
34
+
35
+ E479 = t::ID.new(:E479 , "Functional Identifier Code" , 2, 2,
36
+ s::CodeList.build(
37
+ "BE" => "Benefit Enrollment and Maintenance",
38
+ "FA" => "Functional or Implementation Acknowledgment Transaction Sets",
39
+ "HC" => "Health Care Claim",
40
+ "HI" => "Health Care Services Review Information",
41
+ "HN" => "Health Care Information Status Notification",
42
+ "HP" => "Health Care Claim Payment/Advice",
43
+ "HS" => "Eligibility, Coverage or Benefit Inquiry",
44
+ "HR" => "Health Care Claim Status Request",
45
+ "RA" => "Payment Order/Remittance Advice"))
46
+
47
+ E480 = t::AN.new(:E480 , "Version / Release / Identifier Code" , 1, 12,
48
+ s::CodeList.external("881"))
49
+
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,18 @@
1
+ module Stupidedi
2
+ module Versions
3
+ module FunctionalGroups
4
+ module FortyTen
5
+
6
+ #
7
+ # @see X222.pdf A.1.3.8 Condition Designator
8
+ #
9
+ module ElementReqs
10
+ Mandatory = Schema::ElementReq.new(true, false, "M")
11
+ Optional = Schema::ElementReq.new(false, false, "O")
12
+ Relational = Schema::ElementReq.new(false, false, "X")
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,527 @@
1
+ module Stupidedi
2
+ module Versions
3
+ module FunctionalGroups
4
+ module FortyTen
5
+ module ElementTypes
6
+
7
+ #
8
+ # Simple element definition for date elements
9
+ #
10
+ # @see DateVal
11
+ # @see X222.pdf A.1.3.1.5 Date
12
+ #
13
+ class DT < SimpleElementDef
14
+ def initialize(id, name, min_length, max_length, description = nil, parent = nil)
15
+ super(id, name, min_length, max_length, description, parent)
16
+
17
+ unless min_length == 6 or min_length == 8
18
+ raise ArgumentError,
19
+ "min_length must be either 6 or 8"
20
+ end
21
+
22
+ unless max_length == 6 or max_length == 8
23
+ raise ArgumentError,
24
+ "max_length must be either 6 or 8"
25
+ end
26
+ end
27
+
28
+ def companion
29
+ DateVal
30
+ end
31
+ end
32
+
33
+ #
34
+ # @see X222.pdf B.1.1.3.1.5 Date
35
+ #
36
+ class DateVal < Values::SimpleElementVal
37
+
38
+ def date?
39
+ true
40
+ end
41
+
42
+ def too_long?
43
+ false
44
+ end
45
+
46
+ def too_short?
47
+ false
48
+ end
49
+
50
+ #
51
+ # Models invalid dates, either with a bad format or a date that
52
+ # does not exist (eg Febuary 30th 2000)
53
+ #
54
+ class Invalid < DateVal
55
+
56
+ # @return [Object]
57
+ attr_reader :value
58
+
59
+ def initialize(value, usage, position)
60
+ super(usage, position)
61
+ @value = value
62
+ end
63
+
64
+ def valid?
65
+ false
66
+ end
67
+
68
+ def empty?
69
+ false
70
+ end
71
+
72
+ def inspect
73
+ id = definition.bind do |d|
74
+ "[#{'% 5s' % d.id}: #{d.name}]".bind do |s|
75
+ if usage.forbidden?
76
+ ansi.forbidden(s)
77
+ elsif usage.required?
78
+ ansi.required(s)
79
+ else
80
+ ansi.optional(s)
81
+ end
82
+ end
83
+ end
84
+
85
+ ansi.element("DT.invalid#{id}") << "(#{ansi.invalid(@value.inspect)})"
86
+ end
87
+
88
+ # @return [String]
89
+ def to_s
90
+ ""
91
+ end
92
+
93
+ def ==(other)
94
+ eql?(other) or
95
+ (other.is_a?(Invalid) and @value == other.value)
96
+ end
97
+ end
98
+
99
+ #
100
+ # Empty date value. Shouldn't be directly instantiated -- instead,
101
+ # use the {DateVal.empty} constructor.
102
+ #
103
+ class Empty < DateVal
104
+
105
+ def valid?
106
+ true
107
+ end
108
+
109
+ def empty?
110
+ true
111
+ end
112
+
113
+ # @return [String]
114
+ def inspect
115
+ id = definition.bind do |d|
116
+ "[#{'% 5s' % d.id}: #{d.name}]".bind do |s|
117
+ if usage.forbidden?
118
+ ansi.forbidden(s)
119
+ elsif usage.required?
120
+ ansi.required(s)
121
+ else
122
+ ansi.optional(s)
123
+ end
124
+ end
125
+ end
126
+
127
+ ansi.element("DT.empty#{id}")
128
+ end
129
+
130
+ # @return [String]
131
+ def to_s
132
+ ""
133
+ end
134
+
135
+ # @return [Boolean]
136
+ def ==(other)
137
+ other.is_a?(Empty)
138
+ end
139
+ end
140
+
141
+ #
142
+ # Date with a fully-specified year (with century). Shouldn't be
143
+ # directly instantiated -- instead use the {DateVal.value} constructor
144
+ #
145
+ class Proper < DateVal
146
+ include Comparable
147
+
148
+ # @return [Integer]
149
+ attr_reader :year
150
+
151
+ # @return [Integer]
152
+ attr_reader :month
153
+
154
+ # @return [Integer]
155
+ attr_reader :day
156
+
157
+ def initialize(year, month, day, usage, position)
158
+ @year, @month, @day = year, month, day
159
+
160
+ begin
161
+ # Check that date is valid
162
+ @value = ::Date.civil(@year, @month, @day)
163
+ rescue ArgumentError
164
+ raise Exceptions::InvalidElementError,
165
+ "invalid date year: #{year}, month: #{month}, day: #{day}"
166
+ end
167
+
168
+ super(usage, position)
169
+ end
170
+
171
+ # @return [Proper]
172
+ def copy(changes = {})
173
+ Proper.new \
174
+ changes.fetch(:year, @year),
175
+ changes.fetch(:month, @month),
176
+ changes.fetch(:day, @day),
177
+ changes.fetch(:usage, usage),
178
+ changes.fetch(:position, position)
179
+ end
180
+
181
+ def valid?
182
+ true
183
+ end
184
+
185
+ def empty?
186
+ false
187
+ end
188
+
189
+ def proper?
190
+ true
191
+ end
192
+
193
+ # @return [Date]
194
+ def to_date
195
+ @value
196
+ end
197
+
198
+ # @return [Time]
199
+ def to_time(hour = nil, minute = nil, second = nil)
200
+ if hour.is_a?(TimeVal) and not hour.empty?
201
+ hour, minute, second = hour.hour, hour.minute, hour.second
202
+ end
203
+
204
+ if not second.nil?
205
+ Time.utc(@year, @month, @day, hour, minute, second)
206
+ elsif not minute.nil?
207
+ Time.utc(@year, @month, @day, hour, minute)
208
+ elsif not hour.nil?
209
+ Time.utc(@year, @month, @day, hour)
210
+ else
211
+ Time.utc(@year, @month, @day)
212
+ end
213
+ end
214
+
215
+ # @return [Proper] self
216
+ def oldest(date)
217
+ self
218
+ end
219
+
220
+ # @return [Proper] self
221
+ def newest(date)
222
+ self
223
+ end
224
+
225
+ # @return [Proper] self
226
+ def future
227
+ self
228
+ end
229
+
230
+ # @return [Proper] self
231
+ def past
232
+ self
233
+ end
234
+
235
+ # @return [String]
236
+ def inspect
237
+ id = definition.bind do |d|
238
+ "[#{'% 5s' % d.id}: #{d.name}]".bind do |s|
239
+ if usage.forbidden?
240
+ ansi.forbidden(s)
241
+ elsif usage.required?
242
+ ansi.required(s)
243
+ else
244
+ ansi.optional(s)
245
+ end
246
+ end
247
+ end
248
+
249
+ ansi.element("DT.value#{id}") << "(#{'%04d-%02d-%02d' % [@year, @month, @day]})"
250
+ end
251
+
252
+ # @return [String]
253
+ def to_s
254
+ '%04d%02d%02d' % [@year, @month, @day]
255
+ end
256
+
257
+ # @return -1, 0, 1
258
+ def <=>(other)
259
+ if @year < other.year
260
+ -1
261
+ elsif @year > other.year
262
+ 1
263
+ elsif @month < other.month
264
+ -1
265
+ elsif @month > other.month
266
+ 1
267
+ elsif @day < other.day
268
+ -1
269
+ elsif @day > other.day
270
+ 1
271
+ else
272
+ 0
273
+ end
274
+ end
275
+ end
276
+
277
+ #
278
+ # Date with a partially-specified year (two digits, missing century).
279
+ # Shouldn't be directly instantiated -- instead, use the constuctor
280
+ # method {DateVal.value}
281
+ #
282
+ class Improper < DateVal
283
+
284
+ # @return [Integer]
285
+ attr_reader :year
286
+
287
+ # @return [Integer]
288
+ attr_reader :month
289
+
290
+ # @return [Integer]
291
+ attr_reader :day
292
+
293
+ def initialize(year, month, day, usage, position)
294
+ @year, @month, @day = year, month, day
295
+
296
+ # Check that date is reasonably valid
297
+ unless @year.between?(0, 99) and @month.between?(1, 12) and @day.between?(1, 31)
298
+ raise Exceptions::InvalidElementError,
299
+ "invalid date year: #{year}, month: #{month}, day: #{day}"
300
+ end
301
+
302
+ super(usage, position)
303
+ end
304
+
305
+ # @return [Improper]
306
+ def copy(changes = {})
307
+ Improper.new \
308
+ changes.fetch(:year, @year),
309
+ changes.fetch(:month, @month),
310
+ changes.fetch(:day, @day),
311
+ changes.fetch(:usage, usage),
312
+ changes.fetch(:position, position)
313
+ end
314
+
315
+ def valid?
316
+ true
317
+ end
318
+
319
+ def empty?
320
+ false
321
+ end
322
+
323
+ def proper?
324
+ false
325
+ end
326
+
327
+ # Create a proper date using the given century `cc`
328
+ #
329
+ # @example
330
+ # DateVal.value("501015").century(19) #=> DateVal.value("19501230")
331
+ #
332
+ # @return [Proper]
333
+ def century(cc)
334
+ Proper.new(100 * cc + @year, @month, @day, usage, position)
335
+ end
336
+
337
+ # Create a proper date which cannot be older than the given `date`
338
+ # and cannot be newer than one year after the given `date`.
339
+ #
340
+ # @example
341
+ # DateVal.value("501015").oldest(Date.civil(1950, 10, 20)) #=> DateVal.value("20501015")
342
+ # DateVal.value("501015").oldest(Date.civil(1950, 10, 15)) #=> DateVal.value("19501015")
343
+ # DateVal.value("501015").oldest(Date.civil(1950, 10, 10)) #=> DateVal.value("19501015")
344
+ #
345
+ # @return [Proper]
346
+ def oldest(date)
347
+ cc, yy = date.year.divmod(100)
348
+
349
+ if @year < yy
350
+ century(cc + 1)
351
+ elsif @year > yy
352
+ century(cc)
353
+ else
354
+ if @month < date.month
355
+ century(cc + 1)
356
+ elsif @month > date.month
357
+ century(cc)
358
+ else
359
+ if @day < date.day
360
+ century(cc + 1)
361
+ else
362
+ century(cc)
363
+ end
364
+ end
365
+ end
366
+
367
+ end
368
+
369
+ # Create a proper date which cannot be newer than the given `date`
370
+ # and cannot be older than one year before the given `date`.
371
+ #
372
+ # @example
373
+ # DateVal.value("501015").newest(Date.civil(1950, 10, 20)) #=> DateVal.value("19501015")
374
+ # DateVal.value("501015").newest(Date.civil(1950, 10, 15)) #=> DateVal.value("19501015")
375
+ # DateVal.value("501015").newest(Date.civil(1950, 10, 10)) #=> DateVal.value("18501015")
376
+ #
377
+ # @return [Proper]
378
+ def newest(date)
379
+ cc, yy = date.year.divmod(100)
380
+
381
+ if @year < yy
382
+ century(cc)
383
+ elsif @year > yy
384
+ century(cc - 1)
385
+ else
386
+ if @month < date.month
387
+ century(cc)
388
+ elsif @month > date.month
389
+ century(cc - 1)
390
+ else
391
+ if @day <= date.day
392
+ century(cc)
393
+ else
394
+ century(cc - 1)
395
+ end
396
+ end
397
+ end
398
+ end
399
+
400
+ # Create a proper date which cannot be newer than the current date
401
+ #
402
+ # @return [Proper]
403
+ def past
404
+ newest(Date.today)
405
+ end
406
+
407
+ # Create a proper date which cannot be older than the current date
408
+ #
409
+ # @return [Proper]
410
+ def future
411
+ oldest(Date.today)
412
+ end
413
+
414
+ # @return [String]
415
+ def inspect
416
+ id = definition.bind do |d|
417
+ "[#{'% 5s' % d.id}: #{d.name}]".bind do |s|
418
+ if usage.forbidden?
419
+ ansi.forbidden(s)
420
+ elsif usage.required?
421
+ ansi.required(s)
422
+ else
423
+ ansi.optional(s)
424
+ end
425
+ end
426
+ end
427
+
428
+ ansi.element("DT.value#{id}") << "(XX#{'%02d-%02d-%02d' % [@year, @month, @day]})"
429
+ end
430
+
431
+ # @return [String]
432
+ def to_s
433
+ '%04d%02d%02d' % [@year, @month, @day]
434
+ end
435
+
436
+ # @note Not commutative
437
+ # @return [Boolean]
438
+ def ==(other)
439
+ eql?(other) or
440
+ (@day == other.day and
441
+ @year == other.year and
442
+ @month == other.month)
443
+ end
444
+ end
445
+
446
+ end
447
+
448
+ class << DateVal
449
+ # @group Constructors
450
+ ###################################################################
451
+
452
+ # @return [DateVal::Empty]
453
+ def empty(usage, position)
454
+ DateVal::Empty.new(usage, position)
455
+ end
456
+
457
+ # @return [DateVal]
458
+ def value(object, usage, position)
459
+ if object.blank?
460
+ self::Empty.new(usage, position)
461
+
462
+ elsif object.is_a?(String) or object.is_a?(StringVal)
463
+ string = object.to_s
464
+
465
+ if string.length < 6
466
+ self::Invalid.new(object, usage, position)
467
+ else
468
+ day = string.slice(-2, 2).to_i
469
+ month = string.slice(-4, 2).to_i
470
+ year = string.slice( 0..-5)
471
+
472
+ if year.length < 4
473
+ self::Improper.new(year.to_i, month, day, usage, position)
474
+ else
475
+ self::Proper.new(year.to_i, month, day, usage, position)
476
+ end
477
+ end
478
+
479
+ elsif object.respond_to?(:year) and object.respond_to?(:month) and object.respond_to?(:day)
480
+ self::Proper.new(object.year, object.month, object.day, usage, position)
481
+
482
+ elsif object.is_a?(DateVal::Improper)
483
+ self::Improper.new(object.year, object.month, object.day, usage, position)
484
+
485
+ else
486
+ self::Invalid.new(object, usage, position)
487
+ end
488
+
489
+ rescue Exceptions::InvalidElementError
490
+ self::Invalid.new(object, usage, position)
491
+ end
492
+
493
+ # @return [DateVal]
494
+ def parse(string, usage, position)
495
+ if string.length < 6
496
+ self::Invalid.new(string, usage, position)
497
+ else
498
+ day = string.slice(-2, 2).to_i
499
+ month = string.slice(-4, 2).to_i
500
+ year = string.slice( 0..-5)
501
+
502
+ if year.length < 4
503
+ self::Improper.new(year.to_i, month, day, usage, position)
504
+ else
505
+ self::Proper.new(year.to_i, month, day, usage, position)
506
+ end
507
+ end
508
+ rescue Exceptions::InvalidElementError
509
+ self::Invalid.new(string, usage, position)
510
+ end
511
+
512
+ # @endgroup
513
+ ###################################################################
514
+ end
515
+
516
+ # Prevent direct instantiation of abstract class DateVal
517
+ DateVal.eigenclass.send(:protected, :new)
518
+ DateVal::Empty.eigenclass.send(:public, :new)
519
+ DateVal::Proper.eigenclass.send(:public, :new)
520
+ DateVal::Invalid.eigenclass.send(:public, :new)
521
+ DateVal::Improper.eigenclass.send(:public, :new)
522
+
523
+ end
524
+ end
525
+ end
526
+ end
527
+ end