csv2hash 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +81 -37
- data/ReleaseNotes.md +9 -1
- data/bin/launch_irb +1 -0
- data/lib/csv2hash/adapters/base.rb +0 -1
- data/lib/csv2hash/cell.rb +11 -0
- data/lib/csv2hash/definition.rb +54 -25
- data/lib/csv2hash/expectation.rb +10 -0
- data/lib/csv2hash/parser/collection.rb +28 -22
- data/lib/csv2hash/parser/mapping.rb +6 -6
- data/lib/csv2hash/registry.rb +13 -0
- data/lib/csv2hash/structure_validator.rb +1 -0
- data/lib/csv2hash/validator/collection.rb +19 -13
- data/lib/csv2hash/validator/mapping.rb +13 -9
- data/lib/csv2hash/validator.rb +14 -13
- data/lib/csv2hash/version.rb +1 -1
- data/lib/csv2hash.rb +20 -0
- data/spec/csv2hash/definition_spec.rb +55 -52
- data/spec/csv2hash/parser/collection_spec.rb +49 -44
- data/spec/csv2hash/parser/mapping_spec.rb +31 -26
- data/spec/csv2hash/structure_validator_spec.rb +66 -65
- data/spec/csv2hash/validator/collection_spec.rb +63 -55
- data/spec/csv2hash/validator/mapping_spec.rb +82 -78
- data/spec/csv2hash/validator_spec.rb +25 -24
- data/spec/csv2hash_spec.rb +15 -1
- metadata +6 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12502614a6a2f8d3243b4b35152bc6dc33cc3f60
|
4
|
+
data.tar.gz: 235432257ee6d4e907aaa900f5090fc284fc80db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f597444c037b909413309e3570374c074a18e96463c40c1c7979cd5aeec5f96f6203ade714959c4ca930341e90d4b67a39f2b3718f02c57e85cf4882b6594d5
|
7
|
+
data.tar.gz: e9488827e829ecdc086791c8beadc0afcf5dd868327fbf0c78a479f963d19608a50e581d6974366dacbac9fed4ce289741c8c9971098dddbf90f7e374e0f8bb2
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -28,6 +28,19 @@ Or install it yourself as:
|
|
28
28
|
|
29
29
|
Parsing is based on rules, you must defined rules of parsing
|
30
30
|
|
31
|
+
### DSL
|
32
|
+
|
33
|
+
Csv2hash::Main.generate_definition :name do
|
34
|
+
set_type { Definition::MAPPING }
|
35
|
+
set_header_size { 2 } # 0 by default
|
36
|
+
set_structure_rules {{ 'MaxColumns' => 2 }}
|
37
|
+
mapping do
|
38
|
+
cell position: [0,0], key: 'gender'
|
39
|
+
cell position: [1,0], key: 'name'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
Csv2hash::Main[:name] # Access anywhere
|
43
|
+
|
31
44
|
### Rules
|
32
45
|
|
33
46
|
You should declared a definition for you CSV, and then define for each cell what you would expect.
|
@@ -37,31 +50,31 @@ Example :
|
|
37
50
|
If you want the very first cell, located on the first line and on the first column to be a string with values are either 'yes' either 'no', you can write the following validation rule:
|
38
51
|
|
39
52
|
```
|
40
|
-
|
53
|
+
cell name: 'aswering', type: 'string', values: ['yes', 'no'], position: [0,0]
|
41
54
|
```
|
42
55
|
|
43
56
|
:type attribute has 'string' for default value, therefore you can just write this:
|
44
57
|
|
45
58
|
```
|
46
|
-
|
59
|
+
cell name: 'aswering', values: ['yes', 'no'], position: [0,0]
|
47
60
|
```
|
48
61
|
|
49
62
|
You can define you own message but default message is 'undefined :key on :position'
|
50
63
|
|
51
64
|
```
|
52
|
-
|
65
|
+
cell name: 'aswering', values: ['yes', 'no'], position: [0,0], message: 'this value is not supported'
|
53
66
|
```
|
54
67
|
|
55
68
|
You can also define Range of values
|
56
69
|
|
57
70
|
```
|
58
|
-
|
71
|
+
cell name: 'score', values: 0..5, position: [0,0]
|
59
72
|
```
|
60
73
|
|
61
74
|
The message is parsed:
|
62
75
|
|
63
76
|
```
|
64
|
-
|
77
|
+
cell ..., message: 'value of :name is not supported, please you one of :values'
|
65
78
|
```
|
66
79
|
|
67
80
|
It produces :
|
@@ -119,20 +132,21 @@ Precise position validation sample:
|
|
119
132
|
end
|
120
133
|
|
121
134
|
def data
|
122
|
-
@data_wrapper ||= Csv2hash::Main.new(
|
135
|
+
@data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:<definition_name>], file_path_or_data).parse
|
123
136
|
end
|
124
137
|
|
125
138
|
private
|
126
139
|
|
127
|
-
def rules
|
128
|
-
[].tap do |mapping|
|
129
|
-
mapping << { position: [2,1], key: 'first_name' }
|
130
|
-
mapping << { position: [3,1], key: 'last_name' }
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
140
|
def definition
|
135
|
-
|
141
|
+
Main.generate_definition :my_defintion do
|
142
|
+
set_type { Definition::MAPPING }
|
143
|
+
set_header_size { 1 }
|
144
|
+
mapping do
|
145
|
+
cell position: [2,1], key: 'first_name'
|
146
|
+
cell position: [3,1], key: 'last_name'
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
136
150
|
end
|
137
151
|
|
138
152
|
end
|
@@ -159,23 +173,28 @@ Collection validation sample:
|
|
159
173
|
end
|
160
174
|
|
161
175
|
def data
|
162
|
-
@data_wrapper ||= Csv2hash::Main.new(
|
176
|
+
@data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:<definition_name>], file_path_or_data).parse
|
163
177
|
end
|
164
178
|
|
165
179
|
private
|
166
180
|
|
167
|
-
def rules
|
168
|
-
[].tap do |mapping|
|
169
|
-
mapping << { position: 0, key: 'nickname' }
|
170
|
-
mapping << { position: 1, key: 'first_name' }
|
171
|
-
mapping << { position: 2, key: 'last_name' }
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
181
|
def definition
|
176
182
|
Csv2Hash::Definition.new(rules, type = Csv2Hash::Definition::COLLECTION, header_size: 1)
|
177
183
|
end
|
178
184
|
|
185
|
+
def definition
|
186
|
+
Main.generate_definition :my_defintion do
|
187
|
+
set_type { Definition::COLLECTION }
|
188
|
+
set_header_size { 1 }
|
189
|
+
mapping do
|
190
|
+
cell position: 0, key: 'nickname'
|
191
|
+
cell position: 1, key: 'first_name'
|
192
|
+
cell position: 2, key: 'last_name'
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
179
198
|
end
|
180
199
|
```
|
181
200
|
|
@@ -194,22 +213,23 @@ Current validations are: MinColumn, MaxColumn
|
|
194
213
|
end
|
195
214
|
|
196
215
|
def data
|
197
|
-
@data_wrapper ||= Csv2hash::Main.new(
|
216
|
+
@data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:<definition_name>], file_path_or_data).parse
|
198
217
|
end
|
199
218
|
|
200
219
|
private
|
201
220
|
|
202
|
-
def rules
|
203
|
-
[].tap do |mapping|
|
204
|
-
mapping << { position: 0, key: 'nickname' }
|
205
|
-
mapping << { position: 1, key: 'first_name' }
|
206
|
-
mapping << { position: 2, key: 'last_name' }
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
221
|
def definition
|
211
|
-
|
212
|
-
|
222
|
+
Main.generate_definition :my_defintion do
|
223
|
+
set_type { Definition::COLLECTION }
|
224
|
+
set_header_size { 1 }
|
225
|
+
set_structure_rules {{ 'MinColumns' => 2, 'MaxColumns' => 3 }}
|
226
|
+
mapping do
|
227
|
+
cell position: 0, key: 'nickname'
|
228
|
+
cell position: 1, key: 'first_name'
|
229
|
+
cell position: 2, key: 'last_name'
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
213
233
|
end
|
214
234
|
end
|
215
235
|
```
|
@@ -219,7 +239,7 @@ Current validations are: MinColumn, MaxColumn
|
|
219
239
|
You can define the number of rows to skip in the header of the CSV.
|
220
240
|
|
221
241
|
```
|
222
|
-
|
242
|
+
set_header_size { 1 }
|
223
243
|
```
|
224
244
|
|
225
245
|
### Parser and configuration
|
@@ -343,8 +363,8 @@ For downcase validation
|
|
343
363
|
in your rule
|
344
364
|
|
345
365
|
```
|
346
|
-
|
347
|
-
message: 'your data should be written in lowercase only.'
|
366
|
+
cell position: [0,0], key: 'name', extra_validator: DowncaseValidator.new,
|
367
|
+
message: 'your data should be written in lowercase only.'
|
348
368
|
```
|
349
369
|
|
350
370
|
Csv data
|
@@ -353,6 +373,30 @@ Csv data
|
|
353
373
|
[ [ 'Foo' ] ]
|
354
374
|
```
|
355
375
|
|
376
|
+
# Upgrading
|
377
|
+
|
378
|
+
# Upgrading from 0.5 to 0.6
|
379
|
+
|
380
|
+
Introduce DSL
|
381
|
+
|
382
|
+
Prior to 0.6 :
|
383
|
+
|
384
|
+
```
|
385
|
+
rules = [{ position: [0,0], key: 'name' }]
|
386
|
+
Csv2hash::Definition.new(rules, Definition::MAPPING, options={})
|
387
|
+
|
388
|
+
```
|
389
|
+
|
390
|
+
Starting from 0.6 :
|
391
|
+
|
392
|
+
```
|
393
|
+
Csv2hash::Main.generate_definition :foo do
|
394
|
+
set_type { Definition::MAPPING }
|
395
|
+
mapping { cell position: [0,0], key: 'name' }
|
396
|
+
end
|
397
|
+
Csv2hash::Main[:foo] # Access anywhere
|
398
|
+
```
|
399
|
+
|
356
400
|
# Upgrading from 0.4 to 0.5
|
357
401
|
|
358
402
|
Signature of ```Csv2hash::Main#new``` has changed too
|
data/ReleaseNotes.md
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
+
### VERSION 0.6.0
|
2
|
+
|
3
|
+
* backwards incompatible changes
|
4
|
+
* Introduce DSL for definition
|
5
|
+
|
6
|
+
* refactoring
|
7
|
+
* replace arguments for rules by DSL of cells
|
8
|
+
|
1
9
|
### VERSION 0.5.0
|
2
10
|
|
3
11
|
* backwards incompatible changes
|
4
12
|
* The signature of Csv2hash::Main#new has changed.
|
5
13
|
|
6
14
|
* refactoring
|
7
|
-
* remove params ``` ignore_blank_line ``` to benefit of options of Hash
|
15
|
+
* remove params ``` ignore_blank_line ``` to benefit of options of Hash
|
8
16
|
|
9
17
|
### VERSION 0.4.0
|
10
18
|
|
data/bin/launch_irb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
irb -r csv2hash -I ./lib
|
@@ -5,7 +5,6 @@ module Csv2hash
|
|
5
5
|
class UnsupportedAdapter < StandardError ; end
|
6
6
|
|
7
7
|
def self.create adapter_name, file_path_or_data
|
8
|
-
# binding.pry
|
9
8
|
load "csv2hash/adapters/#{adapter_name}_adapter.rb"
|
10
9
|
class_eval("Csv2hash::Adapter::#{klass_adapter(adapter_name)}").new file_path_or_data
|
11
10
|
end
|
data/lib/csv2hash/definition.rb
CHANGED
@@ -4,52 +4,81 @@ module Csv2hash
|
|
4
4
|
MAPPING = 'mapping'.freeze
|
5
5
|
COLLECTION = 'collection'.freeze
|
6
6
|
|
7
|
-
TYPES = [MAPPING, COLLECTION]
|
7
|
+
TYPES = [ MAPPING, COLLECTION ]
|
8
8
|
|
9
|
-
attr_accessor :
|
9
|
+
attr_accessor :cells, :structure_rules, :header_size
|
10
|
+
attr_reader :type, :name
|
10
11
|
|
11
|
-
def initialize
|
12
|
-
|
13
|
-
self.
|
12
|
+
def initialize name, &blk
|
13
|
+
@name = name
|
14
|
+
self.cells = []
|
15
|
+
self.header_size = 0
|
16
|
+
self.structure_rules = {}
|
17
|
+
instance_eval(&blk) if block_given?
|
18
|
+
end
|
19
|
+
|
20
|
+
def mapping &blk
|
21
|
+
instance_eval(&blk) if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
def cell *args
|
25
|
+
self.cells << Cell.new(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_header_size &blk
|
29
|
+
self.header_size = yield if block_given?
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_type &blk
|
33
|
+
@type = yield if block_given?
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_structure_rules &blk
|
37
|
+
self.structure_rules = yield if block_given?
|
14
38
|
end
|
15
39
|
|
16
40
|
def validate!
|
17
|
-
|
41
|
+
# binding.pry
|
42
|
+
unless TYPES.include?(@type)
|
18
43
|
raise "not suitable type, please use '#{MAPPING}' or '#{COLLECTION}'"
|
19
44
|
end
|
20
|
-
raise '
|
21
|
-
raise 'structure rules must be a Hash of rules' unless structure_rules.class == Hash
|
45
|
+
raise 'cells must be an Array of cell' unless self.cells.class == Array
|
46
|
+
raise 'structure rules must be a Hash of rules' unless self.structure_rules.class == Hash
|
22
47
|
end
|
23
48
|
|
24
49
|
def default!
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
50
|
+
# binding.pry
|
51
|
+
cells.each do |cell|
|
52
|
+
cell.rules.fetch(:position)
|
53
|
+
|
54
|
+
default_position cell
|
55
|
+
unless cell.rules.has_key? :message
|
56
|
+
if cell.rules.has_key? :values
|
57
|
+
cell.rules.merge! message: ':key not supported, please use one of :values'
|
30
58
|
else
|
31
|
-
|
59
|
+
cell.rules.merge! message: 'undefined :key on :position'
|
32
60
|
end
|
33
61
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
62
|
+
cell.rules.merge! mappable: true unless cell.rules.has_key? :mappable
|
63
|
+
cell.rules.merge! type: 'string' unless cell.rules.has_key? :type
|
64
|
+
cell.rules.merge! values: nil unless cell.rules.has_key? :values
|
65
|
+
cell.rules.merge! nested: nil unless cell.rules.has_key? :nested
|
66
|
+
cell.rules.merge! allow_blank: false unless cell.rules.has_key? :allow_blank
|
67
|
+
cell.rules.merge! extra_validator: nil unless cell.rules.has_key? :extra_validator
|
40
68
|
end
|
69
|
+
# binding.pry
|
41
70
|
end
|
42
71
|
|
43
72
|
private
|
44
73
|
|
45
|
-
def default_position
|
74
|
+
def default_position cell
|
46
75
|
case type
|
47
76
|
when MAPPING
|
48
|
-
y, x =
|
49
|
-
|
77
|
+
y, x = cell.rules.fetch(:position, ['undefined', 'undefined'])
|
78
|
+
cell.rules.merge! key: "key_#{y}_#{x}" unless cell.rules.has_key? :key
|
50
79
|
when COLLECTION
|
51
|
-
x =
|
52
|
-
|
80
|
+
x = cell.rules.fetch :position
|
81
|
+
cell.rules.merge! key: "key_undefined_#{x}" unless cell.rules.has_key? :key
|
53
82
|
end
|
54
83
|
end
|
55
84
|
|
@@ -1,31 +1,37 @@
|
|
1
|
-
|
2
|
-
include Csv2hash::Parser
|
1
|
+
require_relative '../expectation'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
module Csv2hash
|
4
|
+
module Parser
|
5
|
+
module Collection
|
6
|
+
include Parser
|
7
|
+
include Expectation
|
8
|
+
|
9
|
+
def fill!
|
10
|
+
self.data = {}.tap do |data_computed|
|
11
|
+
data_computed[:data] ||= []
|
12
|
+
self.data_source.each_with_index do |line, y|
|
13
|
+
next if unexpected_line?(line, y)
|
14
|
+
data_computed[:data] << {}.tap do |data_parsed|
|
15
|
+
fill_it data_parsed, line
|
16
|
+
end
|
17
|
+
end
|
12
18
|
end
|
13
19
|
end
|
14
|
-
end
|
15
|
-
end
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
def fill_it parsed_data, source_data
|
22
|
+
definition.cells.each do |cell|
|
23
|
+
if cell.rules.fetch :mappable
|
24
|
+
x = cell.rules.fetch :position
|
25
|
+
if (nested = cell.rules.fetch :nested)
|
26
|
+
parsed_data[nested] ||= {}
|
27
|
+
parsed_data[nested][cell.rules.fetch(:key)] = source_data[x]
|
28
|
+
else
|
29
|
+
parsed_data[cell.rules.fetch(:key)] = source_data[x]
|
30
|
+
end
|
31
|
+
end
|
26
32
|
end
|
27
33
|
end
|
34
|
+
|
28
35
|
end
|
29
36
|
end
|
30
|
-
|
31
37
|
end
|
@@ -11,14 +11,14 @@ module Csv2hash::Parser::Mapping
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def fill_it parsed_data, source_data
|
14
|
-
definition.
|
15
|
-
if
|
16
|
-
y, x =
|
17
|
-
if (nested =
|
14
|
+
definition.cells.each do |cell|
|
15
|
+
if cell.rules.fetch :mappable
|
16
|
+
y, x = cell.rules.fetch :position
|
17
|
+
if (nested = cell.rules.fetch :nested)
|
18
18
|
parsed_data[nested] ||= {}
|
19
|
-
parsed_data[nested][
|
19
|
+
parsed_data[nested][cell.rules.fetch(:key)] = source_data[y][x]
|
20
20
|
else
|
21
|
-
parsed_data[
|
21
|
+
parsed_data[cell.rules.fetch(:key)] = source_data[y][x]
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -1,18 +1,24 @@
|
|
1
|
-
|
2
|
-
include Csv2hash::Validator
|
1
|
+
require_relative '../expectation'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
end
|
3
|
+
module Csv2hash
|
4
|
+
module Validator
|
5
|
+
module Collection
|
6
|
+
include Validator
|
7
|
+
include Expectation
|
11
8
|
|
12
|
-
|
9
|
+
def validate_data!
|
10
|
+
self.data_source.each_with_index do |line, y|
|
11
|
+
next if unexpected_line?(line, y)
|
12
|
+
validate_rules y
|
13
|
+
end
|
14
|
+
end
|
13
15
|
|
14
|
-
|
15
|
-
[nil, _position]
|
16
|
-
end
|
16
|
+
protected
|
17
17
|
|
18
|
+
def position _position
|
19
|
+
[nil, _position]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
18
24
|
end
|
@@ -1,14 +1,18 @@
|
|
1
|
-
module Csv2hash
|
2
|
-
|
1
|
+
module Csv2hash
|
2
|
+
module Validator
|
3
|
+
module Mapping
|
4
|
+
include Validator
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
6
|
+
def validate_data!
|
7
|
+
validate_rules data_source
|
8
|
+
end
|
7
9
|
|
8
|
-
|
10
|
+
protected
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
def position _position
|
13
|
+
_position
|
14
|
+
end
|
13
15
|
|
16
|
+
end
|
17
|
+
end
|
14
18
|
end
|
data/lib/csv2hash/validator.rb
CHANGED
@@ -2,12 +2,13 @@ module Csv2hash
|
|
2
2
|
module Validator
|
3
3
|
|
4
4
|
def validate_rules y=nil
|
5
|
-
|
6
|
-
|
5
|
+
# binding.pry
|
6
|
+
definition.cells.each do |cell|
|
7
|
+
_y, x = position cell.rules.fetch(:position)
|
7
8
|
begin
|
8
|
-
validate_cell (_y||y), x,
|
9
|
+
validate_cell (_y||y), x, cell
|
9
10
|
rescue => e
|
10
|
-
self.errors << { y: (_y||y), x: x, message: e.message, key:
|
11
|
+
self.errors << { y: (_y||y), x: x, message: e.message, key: cell.rules.fetch(:key) }
|
11
12
|
raise if break_on_failure
|
12
13
|
end
|
13
14
|
end
|
@@ -17,14 +18,14 @@ module Csv2hash
|
|
17
18
|
|
18
19
|
protected
|
19
20
|
|
20
|
-
def validate_cell y, x,
|
21
|
+
def validate_cell y, x, cell
|
21
22
|
value = data_source[y][x] rescue nil
|
22
23
|
begin
|
23
|
-
raise unless value unless
|
24
|
-
if (extra_validator =
|
25
|
-
raise unless extra_validator.valid?
|
24
|
+
raise unless value unless cell.rules.fetch :allow_blank
|
25
|
+
if (extra_validator = cell.rules.fetch :extra_validator) && extra_validator.kind_of?(Csv2hash::ExtraValidator)
|
26
|
+
raise unless extra_validator.valid? cell.rules, value
|
26
27
|
else
|
27
|
-
if value && (values =
|
28
|
+
if value && (values = cell.rules.fetch :values)
|
28
29
|
if values.class == Range
|
29
30
|
raise unless values.include?(value.to_f)
|
30
31
|
else
|
@@ -33,13 +34,13 @@ module Csv2hash
|
|
33
34
|
end
|
34
35
|
end
|
35
36
|
rescue => e
|
36
|
-
raise message(
|
37
|
+
raise message(cell, y, x)
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
40
|
-
def message
|
41
|
-
msg =
|
42
|
-
|
41
|
+
def message cell, y, x
|
42
|
+
msg = cell.rules.fetch(:message).tap do |msg|
|
43
|
+
cell.rules.each { |key, value| msg.gsub!(":#{key.to_s}", value.to_s) unless key == :position }
|
43
44
|
end
|
44
45
|
msg.gsub ':position', "[#{y}, #{x}]"
|
45
46
|
end
|
data/lib/csv2hash/version.rb
CHANGED
data/lib/csv2hash.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require_relative 'csv2hash/version'
|
2
|
+
require_relative 'csv2hash/registry'
|
3
|
+
require_relative 'csv2hash/cell'
|
2
4
|
require_relative 'csv2hash/definition'
|
3
5
|
require_relative 'csv2hash/validator'
|
4
6
|
require_relative 'csv2hash/validator/mapping'
|
@@ -26,6 +28,24 @@ module Csv2hash
|
|
26
28
|
class Main
|
27
29
|
include Csv2hash::StructureValidator
|
28
30
|
|
31
|
+
class << self
|
32
|
+
|
33
|
+
def generate_definition name, &block
|
34
|
+
definition = Definition.new name, &block
|
35
|
+
Main[name] = definition
|
36
|
+
end
|
37
|
+
|
38
|
+
def [] definition_name
|
39
|
+
@@registry[definition_name]
|
40
|
+
end
|
41
|
+
|
42
|
+
def []= definition_name, role
|
43
|
+
@@registry[definition_name] = role
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
@@registry = Registry.new
|
48
|
+
|
29
49
|
attr_accessor :definition, :file_path_or_data, :data, :notifier, :break_on_failure, :errors, :options
|
30
50
|
|
31
51
|
def initialize definition, file_path_or_data, *args
|