csv2hash 0.6.2 → 0.6.3

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -5
  3. data/.yardoc/checksums +25 -0
  4. data/.yardoc/object_types +0 -0
  5. data/.yardoc/objects/root.dat +0 -0
  6. data/.yardoc/proxy_types +0 -0
  7. data/CHANGELOG.md +8 -0
  8. data/Gemfile +6 -0
  9. data/Gemfile.lock +15 -1
  10. data/README.md +32 -4
  11. data/UPGRADE.md +2 -0
  12. data/bin/generate_doc +3 -0
  13. data/config/example.csv +10 -0
  14. data/config/rules.yml +7 -0
  15. data/doc/Cell.html +282 -0
  16. data/doc/Csv2hash/Adapter/Abstract.html +215 -0
  17. data/doc/Csv2hash/Adapter/Base/UnsupportedAdapter.html +123 -0
  18. data/doc/Csv2hash/Adapter/Base.html +201 -0
  19. data/doc/Csv2hash/Adapter/CsvAdapter.html +348 -0
  20. data/doc/Csv2hash/Adapter/MemoryAdapter.html +348 -0
  21. data/doc/Csv2hash/Adapter.html +117 -0
  22. data/doc/Csv2hash/DataWrapper.html +500 -0
  23. data/doc/Csv2hash/Definition.html +1008 -0
  24. data/doc/Csv2hash/Discover.html +192 -0
  25. data/doc/Csv2hash/Expectation.html +202 -0
  26. data/doc/Csv2hash/ExtraValidator.html +207 -0
  27. data/doc/Csv2hash/Main.html +1298 -0
  28. data/doc/Csv2hash/Notifier.html +189 -0
  29. data/doc/Csv2hash/Parser/Collection.html +283 -0
  30. data/doc/Csv2hash/Parser/Mapping.html +266 -0
  31. data/doc/Csv2hash/Parser.html +121 -0
  32. data/doc/Csv2hash/StructureValidator/Deprecation.html +215 -0
  33. data/doc/Csv2hash/StructureValidator/MaxColumns.html +327 -0
  34. data/doc/Csv2hash/StructureValidator/MinColumns.html +327 -0
  35. data/doc/Csv2hash/StructureValidator/ValidationError.html +123 -0
  36. data/doc/Csv2hash/StructureValidator/Validator.html +184 -0
  37. data/doc/Csv2hash/StructureValidator.html +311 -0
  38. data/doc/Csv2hash/Validator/Collection.html +217 -0
  39. data/doc/Csv2hash/Validator/Mapping.html +200 -0
  40. data/doc/Csv2hash/Validator.html +295 -0
  41. data/doc/Csv2hash.html +131 -0
  42. data/doc/CsvArray.html +200 -0
  43. data/doc/Registry.html +312 -0
  44. data/doc/_index.html +391 -0
  45. data/doc/class_list.html +54 -0
  46. data/doc/css/common.css +1 -0
  47. data/doc/css/full_list.css +57 -0
  48. data/doc/css/style.css +339 -0
  49. data/doc/file.README.html +499 -0
  50. data/doc/file_list.html +56 -0
  51. data/doc/frames.html +26 -0
  52. data/doc/index.html +499 -0
  53. data/doc/js/app.js +219 -0
  54. data/doc/js/full_list.js +178 -0
  55. data/doc/js/jquery.js +4 -0
  56. data/doc/method_list.html +473 -0
  57. data/doc/top-level-namespace.html +114 -0
  58. data/lib/csv2hash/definition.rb +3 -3
  59. data/lib/csv2hash/version.rb +1 -1
  60. data/lib/csv2hash/yaml_loader.rb +33 -0
  61. data/lib/csv2hash.rb +28 -8
  62. data/spec/csv2hash/yaml_loader_spec.rb +20 -0
  63. data/spec/csv2hash_spec.rb +13 -10
  64. metadata +56 -1
@@ -0,0 +1,499 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
+ <title>
7
+ File: README
8
+
9
+ &mdash; Documentation by YARD 0.8.7.4
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ hasFrames = window.top.frames.main ? true : false;
19
+ relpath = '';
20
+ framesUrl = "frames.html#!file.README.html";
21
+ </script>
22
+
23
+
24
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
25
+
26
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
27
+
28
+
29
+ </head>
30
+ <body>
31
+ <div id="header">
32
+ <div id="menu">
33
+
34
+ <a href="_index.html">Index</a> &raquo;
35
+ <span class="title">File: README</span>
36
+
37
+
38
+ <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
39
+ </div>
40
+
41
+ <div id="search">
42
+
43
+ <a class="full_list_link" id="class_list_link"
44
+ href="class_list.html">
45
+ Class List
46
+ </a>
47
+
48
+ <a class="full_list_link" id="method_list_link"
49
+ href="method_list.html">
50
+ Method List
51
+ </a>
52
+
53
+ <a class="full_list_link" id="file_list_link"
54
+ href="file_list.html">
55
+ File List
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <iframe id="search_frame"></iframe>
63
+
64
+ <div id="content"><div id='filecontents'>
65
+ <h1 id="label-Csv2Hash">Csv2Hash</h1>
66
+
67
+ <p><a href="https://codeclimate.com/github/FinalCAD/csv2hash"><img
68
+ src="https://codeclimate.com/github/FinalCAD/csv2hash.png"></a></p>
69
+
70
+ <p><a href="https://gemnasium.com/FinalCAD/csv2hash"><img
71
+ src="https://gemnasium.com/FinalCAD/csv2hash.png"></a></p>
72
+
73
+ <p><a href="https://travis-ci.org/FinalCAD/csv2hash"><img
74
+ src="https://travis-ci.org/FinalCAD/csv2hash.png?branch=master"></a>
75
+ (Travis CI)</p>
76
+
77
+ <p><a href="https://coveralls.io/r/FinalCAD/csv2hash"><img
78
+ src="https://coveralls.io/repos/FinalCAD/csv2hash/badge.png"></a></p>
79
+
80
+ <p>It is a DSL to validate and map a CSV to a Ruby Hash.</p>
81
+
82
+ <h2 id="label-Installation">Installation</h2>
83
+
84
+ <p>Add this line to your application&#39;s Gemfile:</p>
85
+
86
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_gem'>gem</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>csv2hash</span><span class='tstring_end'>&#39;</span></span></code></pre>
87
+
88
+ <p>And then execute:</p>
89
+
90
+ <pre class="code ruby"><code class="ruby">$ bundle</code></pre>
91
+
92
+ <p>Or install it yourself as:</p>
93
+
94
+ <pre class="code ruby"><code class="ruby">$ gem install csv2hash</code></pre>
95
+
96
+ <h2 id="label-Usage">Usage</h2>
97
+
98
+ <p>Parsing is based on rules, you should defined rule for each cells</p>
99
+
100
+ <h3 id="label-DSL">DSL</h3>
101
+
102
+ <pre class="code ruby"><code class="ruby"><span class='const'>Csv2hash</span><span class='op'>::</span><span class='const'>Main</span><span class='period'>.</span><span class='id identifier rubyid_generate_definition'>generate_definition</span> <span class='symbol'>:name</span> <span class='kw'>do</span>
103
+ <span class='id identifier rubyid_set_type'>set_type</span> <span class='lbrace'>{</span> <span class='const'>Definition</span><span class='op'>::</span><span class='const'>MAPPING</span> <span class='rbrace'>}</span>
104
+ <span class='id identifier rubyid_set_header_size'>set_header_size</span> <span class='lbrace'>{</span> <span class='int'>2</span> <span class='rbrace'>}</span> <span class='comment'># 0 by default
105
+ </span> <span class='id identifier rubyid_set_structure_rules'>set_structure_rules</span> <span class='lbrace'>{</span><span class='lbrace'>{</span> <span class='label'>max_columns:</span> <span class='int'>2</span> <span class='rbrace'>}</span><span class='rbrace'>}</span>
106
+ <span class='id identifier rubyid_mapping'>mapping</span> <span class='kw'>do</span>
107
+ <span class='id identifier rubyid_cell'>cell</span> <span class='label'>position:</span> <span class='lbracket'>[</span><span class='int'>0</span><span class='comma'>,</span><span class='int'>0</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='label'>key:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>gender</span><span class='tstring_end'>&#39;</span></span>
108
+ <span class='id identifier rubyid_cell'>cell</span> <span class='label'>position:</span> <span class='lbracket'>[</span><span class='int'>1</span><span class='comma'>,</span><span class='int'>0</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='label'>key:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>name</span><span class='tstring_end'>&#39;</span></span>
109
+ <span class='kw'>end</span>
110
+ <span class='kw'>end</span>
111
+ <span class='const'>Csv2hash</span><span class='op'>::</span><span class='const'>Main</span><span class='lbracket'>[</span><span class='symbol'>:name</span><span class='rbracket'>]</span> <span class='comment'># Access anywhere</span></code></pre>
112
+
113
+ <h3 id="label-Rules">Rules</h3>
114
+
115
+ <p>You should declared a definition of your CSV file, and then define for each
116
+ cell what you would expect.</p>
117
+
118
+ <p>Example :</p>
119
+
120
+ <p>If you want the very first cell, located on the first line and on the first
121
+ column to be a string with values are either &#39;yes&#39; either
122
+ &#39;no&#39;, you can write the following validation rule:</p>
123
+
124
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_cell'>cell</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>aswering</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>type:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>string</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>values:</span> <span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>yes</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>no</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='label'>position:</span> <span class='lbracket'>[</span><span class='int'>0</span><span class='comma'>,</span><span class='int'>0</span><span class='rbracket'>]</span></code></pre>
125
+
126
+ <p><code>:type</code> attribute has <code>String</code> for default value,
127
+ therefore you can just write this:</p>
128
+
129
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_cell'>cell</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>aswering</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>values:</span> <span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>yes</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>no</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='label'>position:</span> <span class='lbracket'>[</span><span class='int'>0</span><span class='comma'>,</span><span class='int'>0</span><span class='rbracket'>]</span></code></pre>
130
+
131
+ <p>You can define you own message but default message is &#39;undefined :key
132
+ on :position&#39;</p>
133
+
134
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_cell'>cell</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>aswering</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>values:</span> <span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>yes</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>no</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='label'>position:</span> <span class='lbracket'>[</span><span class='int'>0</span><span class='comma'>,</span><span class='int'>0</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='label'>message:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>this value is not supported</span><span class='tstring_end'>&#39;</span></span></code></pre>
135
+
136
+ <p>You can also define Range of values</p>
137
+
138
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_cell'>cell</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>score</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>values:</span> <span class='int'>0</span><span class='op'>..</span><span class='int'>5</span><span class='comma'>,</span> <span class='label'>position:</span> <span class='lbracket'>[</span><span class='int'>0</span><span class='comma'>,</span><span class='int'>0</span><span class='rbracket'>]</span></code></pre>
139
+
140
+ <p>The message is parsed:</p>
141
+
142
+ <pre class="code ruby"><code class="ruby">cell ..., message: &#39;value of :name is not supported, please you one of :values&#39;</code></pre>
143
+
144
+ <p>It produces :</p>
145
+
146
+ <pre class="code ruby"><code class="ruby">value of answering is not supported, please use one of [yes, no]</code></pre>
147
+
148
+ <h3 id="label-Default+values">Default values</h3>
149
+
150
+ <p>Only position is required:</p>
151
+ <ul><li>
152
+ <p>:position</p>
153
+ </li></ul>
154
+
155
+ <p>All remaining keys are optionals:</p>
156
+ <ul><li>
157
+ <p>message: &#39;undefined :key on :position&#39;</p>
158
+ </li><li>
159
+ <p>mappable: true</p>
160
+ </li><li>
161
+ <p>type: &#39;string&#39;</p>
162
+ </li><li>
163
+ <p>values: nil</p>
164
+ </li><li>
165
+ <p>nested: nil</p>
166
+ </li><li>
167
+ <p>allow_blank: false</p>
168
+ </li><li>
169
+ <p>extra_validator: nil</p>
170
+ </li></ul>
171
+
172
+ <h2 id="label-Define+where+your+data+is+expected">Define where your data is expected</h2>
173
+
174
+ <p><strong>IMPORTANT!</strong> Position means [Y, X], where Y is rows, X
175
+ columns</p>
176
+
177
+ <p>A definition should be provided. There are 2 types of definitions: * search
178
+ for data at a precise position in the table: <code>y,x</code> * or search
179
+ for data in a column of rows, where all the rows are the same:
180
+ <code>x</code> (column index)</p>
181
+
182
+ <h2 id="label-Samples">Samples</h2>
183
+
184
+ <h3 id="label-%5BMAPPING%5D+Validation+of+cells+with+defined+precision">[MAPPING] Validation of cells with defined precision</h3>
185
+
186
+ <p>Consider the following CSV:</p>
187
+
188
+ <pre class="code ruby"><code class="ruby">| Fields | Person Informations | Optional |
189
+ |-------------|----------------------|----------|
190
+ | Nickname | jo | no |
191
+ | First Name | John | yes |
192
+ | Last Name | Doe | yes |</code></pre>
193
+
194
+ <p>Precise position validation sample:</p>
195
+
196
+ <pre class="code ruby"><code class="ruby">class MyParser
197
+
198
+ attr_accessor :file_path_or_data
199
+
200
+ def initialize file_path_or_data
201
+ @file_path_or_data = file_path_or_data
202
+ end
203
+
204
+ def data
205
+ @data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:&lt;definition_name&gt;], file_path_or_data).parse
206
+ end
207
+
208
+ private
209
+
210
+ def definition
211
+ Main.generate_definition :my_defintion do
212
+ set_type { Definition::MAPPING }
213
+ set_header_size { 1 }
214
+ mapping do
215
+ cell position: [2,1], key: &#39;first_name&#39;
216
+ cell position: [3,1], key: &#39;last_name&#39;
217
+ end
218
+ end
219
+ end
220
+ end
221
+
222
+ end</code></pre>
223
+
224
+ <h3 id="label-Auto+discover+position">Auto discover position</h3>
225
+
226
+ <p>This is a special feature for finding the Y index of row where you data
227
+ start. For instance you have this following data :</p>
228
+
229
+ <pre class="code ruby"><code class="ruby">|---------------|---------------|------|-----|
230
+ | Nickname | jo | | |
231
+ | First Name | John | | |
232
+ | Last Name | Doe | | |
233
+ | | | | |
234
+ | Employment | CEO | | |
235
+ | Post | Doe | | |
236
+ | | | | |
237
+ | | Personal info | Age | 26 |
238
+ | | Sex | Male | |
239
+ | | | | |</code></pre>
240
+
241
+ <p>You want extract <code>Employment</code> information and <code>Personal
242
+ info</code> but we do not know if extra information will not come and break
243
+ our index. This feature can be useful is this case.</p>
244
+
245
+ <p>You must change Y position (rows) by the column index and regex, the parser
246
+ will search on this column the index row of this regex, here our rule :</p>
247
+
248
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_cell'>cell</span> <span class='label'>position:</span> <span class='lbracket'>[</span><span class='int'>4</span><span class='comma'>,</span><span class='int'>1</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='label'>key:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>employment</span><span class='tstring_end'>&#39;</span></span></code></pre>
249
+
250
+ <p>became</p>
251
+
252
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_cell'>cell</span> <span class='label'>position:</span> <span class='lbracket'>[</span><span class='lbracket'>[</span><span class='int'>0</span><span class='comma'>,</span> <span class='tstring'><span class='regexp_beg'>/</span><span class='tstring_content'>Employment</span><span class='regexp_end'>/</span></span><span class='rbracket'>]</span><span class='comma'>,</span><span class='int'>1</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='label'>key:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>employment</span><span class='tstring_end'>&#39;</span></span></code></pre>
253
+
254
+ <h3 id="label-%5BCOLLECTION%5D+Validation+of+a+collection+%28Regular+CSV%29">[COLLECTION] Validation of a collection (Regular CSV)</h3>
255
+
256
+ <p>Consider the following CSV:</p>
257
+
258
+ <pre class="code ruby"><code class="ruby">| Nickname | First Name | Last Name |
259
+ |----------|------------|-----------|
260
+ | jo | John | Doe |
261
+ | ja | Jane | Doe |</code></pre>
262
+
263
+ <p>Collection validation sample:</p>
264
+
265
+ <pre class="code ruby"><code class="ruby">class MyParser
266
+
267
+ attr_accessor :file_path_or_data
268
+
269
+ def initialize file_path_or_data
270
+ @file_path_or_data = file_path_or_data
271
+ end
272
+
273
+ def data
274
+ @data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:&lt;definition_name&gt;], file_path_or_data).parse
275
+ end
276
+
277
+ private
278
+
279
+ def definition
280
+ Csv2Hash::Definition.new(rules, type = Csv2Hash::Definition::COLLECTION, header_size: 1)
281
+ end
282
+
283
+ def definition
284
+ Main.generate_definition :my_defintion do
285
+ set_type { Definition::COLLECTION }
286
+ set_header_size { 1 }
287
+ mapping do
288
+ cell position: 0, key: &#39;nickname&#39;
289
+ cell position: 1, key: &#39;first_name&#39;
290
+ cell position: 2, key: &#39;last_name&#39;
291
+ end
292
+ end
293
+ end
294
+ end
295
+
296
+ end</code></pre>
297
+
298
+ <h3 id="label-Structure+validation+rules">Structure validation rules</h3>
299
+
300
+ <p>You may want to validate some structure, like min or max number of columns,
301
+ definition accepts structure_rules as a key for the third parameter.
302
+ Current validations are: :min_columns, :max_columns</p>
303
+
304
+ <pre class="code ruby"><code class="ruby">class MyParser
305
+
306
+ attr_accessor :file_path_or_data
307
+
308
+ def initialize file_path_or_data
309
+ @file_path_or_data = file_path_or_data
310
+ end
311
+
312
+ def data
313
+ @data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:&lt;definition_name&gt;], file_path_or_data).parse
314
+ end
315
+
316
+ private
317
+
318
+ def definition
319
+ Main.generate_definition :my_defintion do
320
+ set_type { Definition::COLLECTION }
321
+ set_header_size { 1 }
322
+ set_structure_rules {{ min_columns: 2, max_columns: 3 }}
323
+ mapping do
324
+ cell position: 0, key: &#39;nickname&#39;
325
+ cell position: 1, key: &#39;first_name&#39;
326
+ cell position: 2, key: &#39;last_name&#39;
327
+ end
328
+ end
329
+ end
330
+ end
331
+ end</code></pre>
332
+
333
+ <h3 id="label-CSV+Headers">CSV Headers</h3>
334
+
335
+ <p>You can define the number of rows to skip in the header of the CSV.</p>
336
+
337
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_set_header_size'>set_header_size</span> <span class='lbrace'>{</span> <span class='int'>1</span> <span class='rbrace'>}</span></code></pre>
338
+
339
+ <h3 id="label-Parser+and+configuration">Parser and configuration</h3>
340
+
341
+ <p>Pasrer can take several parameters like that:</p>
342
+
343
+ <pre class="code ruby"><code class="ruby">definition, file_path_or_data, ignore_blank_line: false</code></pre>
344
+
345
+ <p>in <code>file_path_or_data</code> attribute you can pass directly an
346
+ <code>Array</code> of data (<code>Array</code> with 2 dimensions) really
347
+ useful for testing, if you don&#39;t care about blank lines in your CSV you
348
+ can ignore them.</p>
349
+
350
+ <h3 id="label-Response">Response</h3>
351
+
352
+ <p>The parser return values wrapper into <code>DataWrapper Object</code>, you
353
+ can call <code>.valid?</code> method on this Object and grab either data or
354
+ errors like that :</p>
355
+
356
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_response'>response</span> <span class='op'>=</span> <span class='id identifier rubyid_parser'>parser</span><span class='period'>.</span><span class='id identifier rubyid_parse'>parse</span>
357
+ <span class='kw'>if</span> <span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_valid?'>valid?</span>
358
+ <span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_data'>data</span>
359
+ <span class='kw'>else</span>
360
+ <span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_errors'>errors</span>
361
+ <span class='kw'>end</span></code></pre>
362
+
363
+ <p>data or errors are Array, but errors can be formatted on csv format with
364
+ .to_csv call</p>
365
+
366
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_errors'>errors</span><span class='period'>.</span><span class='id identifier rubyid_to_csv'>to_csv</span></code></pre>
367
+
368
+ <h2 id="label-Exception+or+Not+%21">Exception or Not !</h2>
369
+
370
+ <p>You can choose into 2 differents modes of parsing, either
371
+ <strong>break_on_failure mode</strong> for throw an exception when rule
372
+ fail or <strong>csv mode</strong> for get csv original data + errors
373
+ throwing into added extra column.</p>
374
+
375
+ <h3 id="label-On+BREAK_ON_FAILURE+MODE">On <strong>BREAK_ON_FAILURE MODE</strong></h3>
376
+
377
+ <p>You need call <code>.parse()</code> with bang <code>!</code></p>
378
+
379
+ <h3 id="label-On+CSV+MODE">On <strong>CSV MODE</strong></h3>
380
+
381
+ <p>You need call <code>.parse()</code> return <code>data_wrapper</code> if
382
+ <code>.parse()</code> is invalid, you can code your own behavior:</p>
383
+
384
+ <p>in your code</p>
385
+
386
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_parser'>parser</span> <span class='op'>=</span> <span class='const'>Csv2hash</span><span class='op'>::</span><span class='const'>Main</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='lparen'>(</span><span class='id identifier rubyid_definition'>definition</span><span class='comma'>,</span> <span class='id identifier rubyid_file_path_or_data'>file_path_or_data</span><span class='comma'>,</span> <span class='label'>ignore_blank_line:</span> <span class='kw'>false</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span>
387
+ <span class='id identifier rubyid_response'>response</span> <span class='op'>=</span> <span class='id identifier rubyid_parser'>parser</span><span class='period'>.</span><span class='id identifier rubyid_parse'>parse</span>
388
+ <span class='kw'>return</span> <span class='id identifier rubyid_response'>response</span> <span class='kw'>if</span> <span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_valid?'>valid?</span>
389
+ <span class='comment'># Whatever</span></code></pre>
390
+
391
+ <p>In the same time Csv2hash call <strong>notify(response)</strong> method
392
+ when CSV parsing fail, you can add your own Notifier:</p>
393
+
394
+ <pre class="code ruby"><code class="ruby"><span class='kw'>module</span> <span class='const'>Csv2hash</span>
395
+ <span class='kw'>module</span> <span class='const'>Plugins</span>
396
+ <span class='kw'>class</span> <span class='const'>Notifier</span>
397
+ <span class='kw'>def</span> <span class='id identifier rubyid_initialize'>initialize</span> <span class='id identifier rubyid_csv2hash'>csv2hash</span>
398
+ <span class='id identifier rubyid_csv2hash'>csv2hash</span><span class='period'>.</span><span class='id identifier rubyid_notifier'>notifier</span><span class='period'>.</span><span class='id identifier rubyid_extend'>extend</span> <span class='const'>NotifierWithEmail</span>
399
+ <span class='kw'>end</span>
400
+
401
+ <span class='kw'>module</span> <span class='const'>NotifierWithEmail</span>
402
+ <span class='kw'>def</span> <span class='id identifier rubyid_notify'>notify</span> <span class='id identifier rubyid_response'>response</span>
403
+ <span class='id identifier rubyid_filename'>filename</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>issues_errors.csv</span><span class='tstring_end'>&#39;</span></span>
404
+ <span class='id identifier rubyid_tempfile'>tempfile</span> <span class='op'>=</span> <span class='const'>Tempfile</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='lbracket'>[</span><span class='id identifier rubyid_filename'>filename</span><span class='comma'>,</span> <span class='const'>File</span><span class='period'>.</span><span class='id identifier rubyid_extname'>extname</span><span class='lparen'>(</span><span class='id identifier rubyid_filename'>filename</span><span class='rparen'>)</span><span class='rbracket'>]</span>
405
+ <span class='const'>File</span><span class='period'>.</span><span class='id identifier rubyid_open'>open</span><span class='lparen'>(</span><span class='id identifier rubyid_tempfile'>tempfile</span><span class='period'>.</span><span class='id identifier rubyid_path'>path</span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>wb</span><span class='tstring_end'>&#39;</span></span><span class='rparen'>)</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_file'>file</span><span class='op'>|</span> <span class='id identifier rubyid_file'>file</span><span class='period'>.</span><span class='id identifier rubyid_write'>write</span> <span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_errors'>errors</span><span class='period'>.</span><span class='id identifier rubyid_to_csv'>to_csv</span> <span class='rbrace'>}</span>
406
+ <span class='comment'># Send mail with csv file + errors and free resource
407
+ </span> <span class='id identifier rubyid_tempfile'>tempfile</span><span class='period'>.</span><span class='id identifier rubyid_unlink'>unlink</span>
408
+ <span class='kw'>end</span>
409
+ <span class='kw'>end</span>
410
+ <span class='kw'>end</span>
411
+ <span class='kw'>end</span>
412
+ <span class='kw'>end</span></code></pre>
413
+
414
+ <p>Or other implementation</p>
415
+
416
+ <h3 id="label-Errors+Format">Errors Format</h3>
417
+
418
+ <p>errors is a Array of Hash</p>
419
+
420
+ <pre class="code ruby"><code class="ruby"><span class='lbrace'>{</span> <span class='label'>y:</span> <span class='int'>1</span><span class='comma'>,</span> <span class='label'>x:</span> <span class='int'>0</span><span class='comma'>,</span> <span class='label'>message:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>message</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>key:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>key</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>value:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_end'>&#39;</span></span> <span class='rbrace'>}</span></code></pre>
421
+
422
+ <h2 id="label-Sample">Sample</h2>
423
+
424
+ <h3 id="label-Csv+data">Csv data</h3>
425
+
426
+ <pre class="code ruby"><code class="ruby">| Fields | Person Informations |
427
+ |-------------|----------------------|
428
+ | Nickname | nil |</code></pre>
429
+
430
+ <h3 id="label-Rule">Rule</h3>
431
+
432
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_cell'>cell</span> <span class='label'>position:</span> <span class='lbracket'>[</span><span class='int'>1</span><span class='comma'>,</span><span class='int'>1</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='label'>key:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>nickname</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>allow_blank:</span> <span class='kw'>false</span></code></pre>
433
+
434
+ <h3 id="label-Error">Error</h3>
435
+
436
+ <pre class="code ruby"><code class="ruby"><span class='lbrace'>{</span> <span class='label'>y:</span> <span class='int'>1</span><span class='comma'>,</span> <span class='label'>x:</span> <span class='int'>1</span><span class='comma'>,</span> <span class='label'>message:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>undefined nikcname on [0, 0]</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>key:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>nickname</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>value:</span> <span class='kw'>nil</span> <span class='rbrace'>}</span></code></pre>
437
+
438
+ <h2 id="label-Personal+Validator+Rule">Personal Validator Rule</h2>
439
+
440
+ <p>You can define your own Validator</p>
441
+
442
+ <p>For downcase validation</p>
443
+
444
+ <pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>DowncaseValidator</span> <span class='op'>&lt;</span> <span class='const'>Csv2hash</span><span class='op'>::</span><span class='const'>ExtraValidator</span>
445
+ <span class='kw'>def</span> <span class='id identifier rubyid_valid?'>valid?</span> <span class='id identifier rubyid_value'>value</span>
446
+ <span class='op'>!</span><span class='op'>!</span><span class='lparen'>(</span><span class='id identifier rubyid_value'>value</span><span class='period'>.</span><span class='id identifier rubyid_match'>match</span> <span class='tstring'><span class='regexp_beg'>/</span><span class='tstring_content'>^[a-z]+$</span><span class='regexp_end'>/</span></span><span class='rparen'>)</span>
447
+ <span class='kw'>end</span>
448
+ <span class='kw'>end</span></code></pre>
449
+
450
+ <p>in your rule</p>
451
+
452
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_cell'>cell</span> <span class='label'>position:</span> <span class='lbracket'>[</span><span class='int'>0</span><span class='comma'>,</span><span class='int'>0</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='label'>key:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>name</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>extra_validator:</span> <span class='const'>DowncaseValidator</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='comma'>,</span>
453
+ <span class='label'>message:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>your data should be written in lowercase only.</span><span class='tstring_end'>&#39;</span></span></code></pre>
454
+
455
+ <p>Csv data</p>
456
+
457
+ <pre class="code ruby"><code class="ruby"><span class='lbracket'>[</span> <span class='lbracket'>[</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Foo</span><span class='tstring_end'>&#39;</span></span> <span class='rbracket'>]</span> <span class='rbracket'>]</span></code></pre>
458
+
459
+ <h1 id="label-Changes">Changes</h1>
460
+
461
+ <p>please refere to <a
462
+ href="https://github.com/FinalCAD/csv2hash/blob/master/CHANGELOG.md">CHANGELOG.md</a>
463
+ doc</p>
464
+
465
+ <h1 id="label-Upgrading">Upgrading</h1>
466
+
467
+ <p>please refere to <a
468
+ href="https://github.com/FinalCAD/csv2hash/blob/master/UPGRADE.md">UPGRADE.md</a>
469
+ doc</p>
470
+
471
+ <h1 id="label-Yard+doc">Yard doc</h1>
472
+
473
+ <p><a
474
+ href="https://github.com/FinalCAD/csv2hash/blob/master/doc/index.html">Documentation</a>
475
+ doc</p>
476
+
477
+ <h2 id="label-Contributing">Contributing</h2>
478
+ <ol><li>
479
+ <p>Fork it</p>
480
+ </li><li>
481
+ <p>Create your feature branch (<code>git checkout -b my-new-feature</code>)</p>
482
+ </li><li>
483
+ <p>Commit your changes (<code>git commit -am &#39;Added some
484
+ feature&#39;</code>)</p>
485
+ </li><li>
486
+ <p>Push to the branch (<code>git push origin my-new-feature</code>)</p>
487
+ </li><li>
488
+ <p>Create new Pull Request</p>
489
+ </li></ol>
490
+ </div></div>
491
+
492
+ <div id="footer">
493
+ Generated on Fri Aug 29 17:12:26 2014 by
494
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
495
+ 0.8.7.4 (ruby-2.1.2).
496
+ </div>
497
+
498
+ </body>
499
+ </html>
@@ -0,0 +1,56 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html>
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+
7
+ <link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" charset="utf-8" />
8
+
9
+ <link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
10
+
11
+
12
+
13
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
14
+
15
+ <script type="text/javascript" charset="utf-8" src="js/full_list.js"></script>
16
+
17
+
18
+ <title>File List</title>
19
+ <base id="base_target" target="_parent" />
20
+ </head>
21
+ <body>
22
+ <script type="text/javascript" charset="utf-8">
23
+ if (window.top.frames.main) {
24
+ document.getElementById('base_target').target = 'main';
25
+ document.body.className = 'frames';
26
+ }
27
+ </script>
28
+ <div id="content">
29
+ <h1 id="full_list_header">File List</h1>
30
+ <div id="nav">
31
+
32
+ <span><a target="_self" href="class_list.html">
33
+ Classes
34
+ </a></span>
35
+
36
+ <span><a target="_self" href="method_list.html">
37
+ Methods
38
+ </a></span>
39
+
40
+ <span><a target="_self" href="file_list.html">
41
+ Files
42
+ </a></span>
43
+
44
+ </div>
45
+ <div id="search">Search: <input type="text" /></div>
46
+
47
+ <ul id="full_list" class="file">
48
+
49
+
50
+ <li class="r1"><span class="object_link"><a href="index.html" title="README">README</a></a></li>
51
+
52
+
53
+ </ul>
54
+ </div>
55
+ </body>
56
+ </html>
data/doc/frames.html ADDED
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
7
+ <title>Documentation by YARD 0.8.7.4</title>
8
+ </head>
9
+ <script type="text/javascript" charset="utf-8">
10
+ window.onload = function() {
11
+ var match = unescape(window.location.hash).match(/^#!(.+)/);
12
+ var name = match ? match[1] : 'index.html';
13
+ name = name.replace(/^(\w+):\/\//, '').replace(/^\/\//, '');
14
+ document.writeln('<frameset cols="20%,*">' +
15
+ '<frame name="list" src="class_list.html" />' +
16
+ '<frame name="main" src="' + escape(name) + '" />' +
17
+ '</frameset>');
18
+ }
19
+ </script>
20
+ <noscript>
21
+ <frameset cols="20%,*">
22
+ <frame name="list" src="class_list.html" />
23
+ <frame name="main" src="index.html" />
24
+ </frameset>
25
+ </noscript>
26
+ </html>