honey_format 0.19.0 → 0.20.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/.travis.yml +3 -3
- data/CHANGELOG.md +12 -0
- data/README.md +23 -8
- data/honey_format.gemspec +1 -1
- data/lib/honey_format/csv.rb +6 -1
- data/lib/honey_format/matrix/header.rb +40 -14
- data/lib/honey_format/matrix/row.rb +1 -1
- data/lib/honey_format/version.rb +1 -1
- metadata +11 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c0136727f1cf1e473ac8a517105158a9c927c5988f525b1640ffced32c5a2fd
|
4
|
+
data.tar.gz: d26d86cd08edbc33f2f9b8399ef2f7c5aade4b35ca4ea7617dc6a21415b72c9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ec8850e11d3ae4039b748738641bacd19ea3ffe9f437e2d93eb407e9d7e7cb2dcc669116f04f2a175855fbc121bad62228dc6dbd022163d033a52e89af6e8e7
|
7
|
+
data.tar.gz: 9ec609fe969d26348c1be54458a79ea24a199085381e82c3bc79d58b5054bb02300759946f520c7b29eb0273e56db290375c791ee4fb2c5fecf10da65954e54b
|
data/.travis.yml
CHANGED
@@ -9,11 +9,11 @@ matrix:
|
|
9
9
|
include:
|
10
10
|
- rvm: 2.3.0
|
11
11
|
install:
|
12
|
-
- gem install bundler --no-
|
12
|
+
- gem install bundler --no-document
|
13
13
|
- bundle install
|
14
14
|
- rvm: 2.5.1
|
15
15
|
install:
|
16
|
-
- gem install bundler --no-
|
16
|
+
- gem install bundler --no-document
|
17
17
|
- bundle install
|
18
18
|
- rvm: 2.6.0-preview3
|
19
19
|
install:
|
@@ -21,7 +21,7 @@ matrix:
|
|
21
21
|
- name: TruffleRuby
|
22
22
|
rvm: system
|
23
23
|
install:
|
24
|
-
- export TRUFFLERUBY_VERSION=1.0.0-
|
24
|
+
- export TRUFFLERUBY_VERSION=1.0.0-rc10
|
25
25
|
- curl -L https://github.com/oracle/truffleruby/releases/download/vm-$TRUFFLERUBY_VERSION/truffleruby-$TRUFFLERUBY_VERSION-linux-amd64.tar.gz | tar xz
|
26
26
|
- export PATH="$PWD/truffleruby-$TRUFFLERUBY_VERSION-linux-amd64/bin:$PATH"
|
27
27
|
- gem install bundler -v 1.16.6 --no-ri --no-rdoc
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# HEAD
|
2
2
|
|
3
|
+
## v0.20.0
|
4
|
+
|
5
|
+
* Support additional header variant, pass hash with `String => Symbol` and/or `String => #call` (callable object). Unmapped keys are converted using the default header converter.
|
6
|
+
```ruby
|
7
|
+
converter = {
|
8
|
+
'First name' => :first_name,
|
9
|
+
'Last name' => -> { :surname }
|
10
|
+
}
|
11
|
+
csv = HoneyFormat::CSV.new(csv_string, header_converter: converter)
|
12
|
+
```
|
13
|
+
* Add `encoding` option to `CSV`
|
14
|
+
|
3
15
|
## v0.19.0
|
4
16
|
|
5
17
|
* Add `method_name` as alias for `header_column` converter
|
data/README.md
CHANGED
@@ -27,8 +27,8 @@ Id,Username,Email
|
|
27
27
|
2,jacob,jacob@example.com
|
28
28
|
CSV
|
29
29
|
csv = HoneyFormat::CSV.new(csv_string, type_map: { id: :integer })
|
30
|
-
csv.columns # => [:id, :username]
|
31
|
-
csv.rows # => [#<Row id=1, username="buren">]
|
30
|
+
csv.columns # => [:id, :username, :email]
|
31
|
+
csv.rows # => [#<Row id=1, username="buren", email="buren@example.com">, #<Row id=2, username="jacob", email="jacob@example.com">]
|
32
32
|
user = csv.rows.first
|
33
33
|
user.id # => 1
|
34
34
|
user.username # => "buren"
|
@@ -248,21 +248,36 @@ csv.columns # => [:ID, :USERNAME]
|
|
248
248
|
|
249
249
|
Pass your own header converter
|
250
250
|
```ruby
|
251
|
-
|
252
|
-
|
251
|
+
# unmapped keys use the default header converter,
|
252
|
+
# mix simple key => value mapping with key => proc
|
253
|
+
converter = {
|
254
|
+
'First^Name' => :first_name,
|
255
|
+
'Username' => -> { :handle }
|
256
|
+
}
|
253
257
|
|
254
|
-
csv_string = "ID,First^Name\n1,Jacob"
|
258
|
+
csv_string = "ID,Username,First^Name\n1,buren,Jacob"
|
255
259
|
user = HoneyFormat::CSV.new(csv_string, header_converter: converter).rows.first
|
256
260
|
user.first_name # => "Jacob"
|
261
|
+
user.handle # => "buren"
|
257
262
|
user.id # => "1"
|
263
|
+
|
264
|
+
# you can also pass a proc or any callable object
|
265
|
+
converter = Class.new do
|
266
|
+
define_singleton_method(:call) { |value, index| "#{value}#{index}" }
|
267
|
+
end
|
268
|
+
# or
|
269
|
+
converter = ->(value, index) { "#{value}#{index}" }
|
270
|
+
user = HoneyFormat::CSV.new(csv_string, header_converter: converter)
|
258
271
|
```
|
259
272
|
|
260
|
-
Missing header values
|
273
|
+
Missing header values are automatically set and deduplicated
|
261
274
|
```ruby
|
262
|
-
csv_string = "first,,third\nval0,val1,val2"
|
275
|
+
csv_string = "first,,third,third\nval0,val1,val2,val3"
|
263
276
|
csv = HoneyFormat::CSV.new(csv_string)
|
264
277
|
user = csv.rows.first
|
265
278
|
user.column1 # => "val1"
|
279
|
+
user.third # => "val2"
|
280
|
+
user.third1 # => "val3"
|
266
281
|
```
|
267
282
|
|
268
283
|
Duplicated header values
|
@@ -302,7 +317,7 @@ user['first^name'] # => "Jacob"
|
|
302
317
|
|
303
318
|
__Errors__
|
304
319
|
|
305
|
-
> When you need
|
320
|
+
> When you need to be extra safe.
|
306
321
|
|
307
322
|
If you want to there are some errors you can rescue
|
308
323
|
```ruby
|
data/honey_format.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.required_ruby_version = '>= 2.3.0'
|
24
24
|
|
25
25
|
spec.add_development_dependency 'benchmark-ips'
|
26
|
-
spec.add_development_dependency 'bundler', '
|
26
|
+
spec.add_development_dependency 'bundler', '> 1.10', '< 3'
|
27
27
|
spec.add_development_dependency 'byebug'
|
28
28
|
spec.add_development_dependency 'rake', '~> 10.0'
|
29
29
|
spec.add_development_dependency 'rspec'
|
data/lib/honey_format/csv.rb
CHANGED
@@ -19,6 +19,7 @@ module HoneyFormat
|
|
19
19
|
# @param header_deduplicator [#call] deduplicates header columns.
|
20
20
|
# @param row_builder [#call] will be called for each parsed row.
|
21
21
|
# @param type_map [Hash] map of column_name => type conversion to perform.
|
22
|
+
# @param encoding [String] CSV encoding (for example "BOM|UTF-16LE:UTF-8").
|
22
23
|
# @param skip_lines [Regexp, String]
|
23
24
|
# Regexp for determining wheter a line is a comment. See CSV skip_lines option.
|
24
25
|
# @raise [HeaderError] super class of errors raised when there is a CSV header error.
|
@@ -46,6 +47,8 @@ module HoneyFormat
|
|
46
47
|
# @example Skip lines all lines starting with '#'
|
47
48
|
# csv = HoneyFormat::CSV.new("name,id\n# some comment\njacob,1", skip_lines: '#')
|
48
49
|
# csv.rows.length # => 1
|
50
|
+
# @example CSV encoding
|
51
|
+
# csv = HoneyFormat::CSV.new(csv_string, encoding: "BOM|UTF-16LE:UTF-8")
|
49
52
|
# @see Matrix#new
|
50
53
|
def initialize(
|
51
54
|
csv,
|
@@ -56,6 +59,7 @@ module HoneyFormat
|
|
56
59
|
header_converter: HoneyFormat.header_converter,
|
57
60
|
header_deduplicator: HoneyFormat.config.header_deduplicator,
|
58
61
|
row_builder: nil,
|
62
|
+
encoding: nil,
|
59
63
|
type_map: {},
|
60
64
|
skip_lines: HoneyFormat.config.skip_lines
|
61
65
|
)
|
@@ -65,7 +69,8 @@ module HoneyFormat
|
|
65
69
|
row_sep: row_delimiter,
|
66
70
|
quote_char: quote_character,
|
67
71
|
skip_blanks: true,
|
68
|
-
skip_lines: skip_lines
|
72
|
+
skip_lines: skip_lines,
|
73
|
+
encoding: encoding
|
69
74
|
)
|
70
75
|
super(
|
71
76
|
csv,
|
@@ -10,10 +10,11 @@ module HoneyFormat
|
|
10
10
|
# Instantiate a Header
|
11
11
|
# @return [Header] a new instance of Header.
|
12
12
|
# @param [Array<String>] header array of strings.
|
13
|
-
# @param converter [#call, Symbol]
|
13
|
+
# @param converter [#call, Symbol, Hash]
|
14
14
|
# header converter that implements a #call method
|
15
15
|
# that takes one column (string) argument OR symbol for a registered
|
16
|
-
# converter registry
|
16
|
+
# converter registry OR a hash mapped to a symbol or something that responds
|
17
|
+
# to #call.
|
17
18
|
# @param deduplicator [#call, Symbol]
|
18
19
|
# header deduplicator that implements a #call method
|
19
20
|
# that takes columns Array<String> argument OR symbol for a registered
|
@@ -93,7 +94,7 @@ module HoneyFormat
|
|
93
94
|
private
|
94
95
|
|
95
96
|
# Set the header converter
|
96
|
-
# @param [Symbol, #call] symbol to known converter
|
97
|
+
# @param [Hash, Symbol, #call] symbol to known converter, object that responds to #call or Hash
|
97
98
|
# @return [nil]
|
98
99
|
def converter=(object)
|
99
100
|
if object.is_a?(Symbol)
|
@@ -101,6 +102,11 @@ module HoneyFormat
|
|
101
102
|
return
|
102
103
|
end
|
103
104
|
|
105
|
+
if object.is_a?(Hash)
|
106
|
+
@converter = hash_converter(object)
|
107
|
+
return
|
108
|
+
end
|
109
|
+
|
104
110
|
@converter = object
|
105
111
|
end
|
106
112
|
|
@@ -134,21 +140,17 @@ module HoneyFormat
|
|
134
140
|
# @param [Integer] index the CSV header column index
|
135
141
|
# @return [Symbol] the converted column
|
136
142
|
def convert_column(column, index)
|
137
|
-
|
138
|
-
@converter.call(column)
|
139
|
-
else
|
140
|
-
@converter.call(column, index)
|
141
|
-
end
|
142
|
-
value.to_sym
|
143
|
+
call_column_builder(@converter, column, index)&.to_sym
|
143
144
|
end
|
144
145
|
|
145
|
-
# Returns the
|
146
|
-
# @
|
147
|
-
|
146
|
+
# Returns the callable object method arity
|
147
|
+
# @param [#arity, #call] callable thing that responds to #call and maybe #arity
|
148
|
+
# @return [Integer] the method arity
|
149
|
+
def callable_arity(callable)
|
148
150
|
# procs and lambdas respond to #arity
|
149
|
-
return
|
151
|
+
return callable.arity if callable.respond_to?(:arity)
|
150
152
|
|
151
|
-
|
153
|
+
callable.method(:call).arity
|
152
154
|
end
|
153
155
|
|
154
156
|
# Raises an error if header column is missing/empty
|
@@ -164,5 +166,29 @@ module HoneyFormat
|
|
164
166
|
]
|
165
167
|
raise(Errors::MissingHeaderColumnError, parts.join(' '))
|
166
168
|
end
|
169
|
+
|
170
|
+
def hash_converter(hash)
|
171
|
+
lambda { |value, index|
|
172
|
+
# support strings and symbol keys interchangeably
|
173
|
+
column = hash.fetch(value) do
|
174
|
+
key = value.respond_to?(:to_sym) ? value.to_sym : value
|
175
|
+
# if column is unmapped use the default header converter
|
176
|
+
hash.fetch(key) { HoneyFormat.header_converter.call(value, index) }
|
177
|
+
end
|
178
|
+
|
179
|
+
# The hash can contain mixed values, Symbol and procs
|
180
|
+
if column.respond_to?(:call)
|
181
|
+
column = call_column_builder(column, value, index)
|
182
|
+
end
|
183
|
+
|
184
|
+
column&.to_sym
|
185
|
+
}
|
186
|
+
end
|
187
|
+
|
188
|
+
def call_column_builder(callable, value, index)
|
189
|
+
return callable.call if callable_arity(callable).zero?
|
190
|
+
return callable.call(value) if callable_arity(callable) == 1
|
191
|
+
callable.call(value, index)
|
192
|
+
end
|
167
193
|
end
|
168
194
|
end
|
@@ -4,7 +4,7 @@ module HoneyFormat
|
|
4
4
|
# Default row builder
|
5
5
|
class Row < Struct
|
6
6
|
# Create a row
|
7
|
-
# @return [
|
7
|
+
# @return [Row] returns an instantiated Row
|
8
8
|
# @example
|
9
9
|
# row_klass = Row.new(:id, :username)
|
10
10
|
# row = row_klass.call('1', 'buren')
|
data/lib/honey_format/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: honey_format
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Burenstam
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|
@@ -28,16 +28,22 @@ dependencies:
|
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.10'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '3'
|
34
37
|
type: :development
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
|
-
- - "
|
41
|
+
- - ">"
|
39
42
|
- !ruby/object:Gem::Version
|
40
43
|
version: '1.10'
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '3'
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: byebug
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -162,8 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
168
|
- !ruby/object:Gem::Version
|
163
169
|
version: '0'
|
164
170
|
requirements: []
|
165
|
-
|
166
|
-
rubygems_version: 2.7.6
|
171
|
+
rubygems_version: 3.0.3
|
167
172
|
signing_key:
|
168
173
|
specification_version: 4
|
169
174
|
summary: Makes working with CSVs as smooth as honey.
|