honey_format 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.md +10 -0
- data/README.md +22 -21
- data/bin/benchmark +4 -4
- data/honey_format.gemspec +1 -0
- data/lib/honey_format/convert_header_value.rb +2 -0
- data/lib/honey_format/csv.rb +9 -4
- data/lib/honey_format/header.rb +5 -0
- data/lib/honey_format/row.rb +3 -6
- data/lib/honey_format/row_builder.rb +21 -0
- data/lib/honey_format/rows.rb +15 -0
- data/lib/honey_format/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ec17df72ebcb22be2365a454c19632f6ee22becc155a525bf66a010f7eec4b2
|
4
|
+
data.tar.gz: b05efbc59d1af2da443fd4c3e72cf573d9fd43b292b644336299411e705a77e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b802e64d2033b5ea9881b30142e88f9d326e7d89416deadd7aa3c2f49c6da3f5b7a03fda057a802a9cebff28c72d5c75cfe48e9fa3a93e68ac808beb480b3d42
|
7
|
+
data.tar.gz: 71682b5a17dae461bbdabece49219e76be07241494b3606849ec5e7198bcf9e6f8e470a0e5a857ff879d5cc48ea796214a93d3ac0793cffb3feb29842e15486e
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
# v0.6.0
|
2
|
+
|
3
|
+
* Add `CSV#to_csv` ([PR#2](https://github.com/buren/honey_format/pull/2))
|
4
|
+
* `csv#rows` returns an instance of `Rows` instead of `Array`
|
5
|
+
|
6
|
+
# v0.3.0 - v0.5.0
|
7
|
+
|
8
|
+
* Add CSV `row_builder` option
|
9
|
+
* ...
|
10
|
+
|
1
11
|
# v0.2.0
|
2
12
|
|
3
13
|
* More explicit exception classes
|
data/README.md
CHANGED
@@ -49,13 +49,22 @@ user.id # => "1"
|
|
49
49
|
user.username # => "buren"
|
50
50
|
```
|
51
51
|
|
52
|
+
Custom row builder
|
52
53
|
```ruby
|
53
54
|
csv_string = "Id, Username\n 1, buren"
|
54
|
-
|
55
|
-
csv = HoneyFormat::CSV.new(csv_string, row_builder:
|
55
|
+
upcase_builder = ->(o) { o.is_a?(String) ? o.upcase : o }
|
56
|
+
csv = HoneyFormat::CSV.new(csv_string, row_builder: upcase_builder)
|
56
57
|
csv.rows # => [#<struct id="1", username="BUREN">]
|
57
58
|
```
|
58
59
|
|
60
|
+
Output CSV
|
61
|
+
```ruby
|
62
|
+
csv_string = "Id, Username\n 1, buren"
|
63
|
+
csv = HoneyFormat::CSV.new(csv_string)
|
64
|
+
csv.rows.each { |row| row.id = nil }
|
65
|
+
csv.to_csv # => "Id, Username\n,buren\n"
|
66
|
+
```
|
67
|
+
|
59
68
|
Validate CSV header
|
60
69
|
```ruby
|
61
70
|
csv_string = "Id, Username\n 1, buren"
|
@@ -95,33 +104,25 @@ If you want to see more usage examples check out the `spec/` directory.
|
|
95
104
|
|
96
105
|
_Note_: This gem, adds some overhead to parsing a CSV string. I've included some benchmarks below, your mileage may vary..
|
97
106
|
|
98
|
-
|
99
|
-
|
100
|
-
124KB (~1000 lines )
|
107
|
+
You can run the benchmarks yourself:
|
101
108
|
|
102
109
|
```
|
103
|
-
|
104
|
-
stdlib CSV 6.000 i/100ms
|
105
|
-
HoneyFormat::CSV 5.000 i/100ms
|
106
|
-
-------------------------------------------------
|
107
|
-
stdlib CSV 64.236 (± 4.7%) i/s - 642.000
|
108
|
-
HoneyFormat::CSV 52.762 (± 5.7%) i/s - 530.000
|
109
|
-
|
110
|
-
Comparison:
|
111
|
-
stdlib CSV: 64.2 i/s
|
112
|
-
HoneyFormat::CSV: 52.8 i/s - 1.22x slower
|
110
|
+
$ bin/benchmark file.csv
|
113
111
|
```
|
114
112
|
|
115
|
-
|
113
|
+
204KB (1k lines)
|
116
114
|
|
117
115
|
```
|
118
|
-
|
119
|
-
|
120
|
-
HoneyFormat::CSV: 0.3 i/s - 1.26x slower
|
116
|
+
stdlib CSV: 48.9 i/s
|
117
|
+
HoneyFormat::CSV: 34.5 i/s - 1.41x slower
|
121
118
|
```
|
122
119
|
|
123
|
-
|
124
|
-
|
120
|
+
19MB (100k lines)
|
121
|
+
|
122
|
+
```
|
123
|
+
stdlib CSV: 0.4 i/s
|
124
|
+
HoneyFormat::CSV: 0.3 i/s - 1.41x slower
|
125
|
+
```
|
125
126
|
|
126
127
|
## Development
|
127
128
|
|
data/bin/benchmark
CHANGED
@@ -5,12 +5,12 @@ require 'honey_format'
|
|
5
5
|
require 'benchmark/ips'
|
6
6
|
require 'csv'
|
7
7
|
|
8
|
-
|
9
|
-
csv = File.read(
|
8
|
+
path = ARGV.first || fail(ArgumentError, '<path_to_csv> argument must be provided')
|
9
|
+
csv = File.read(path)
|
10
10
|
|
11
11
|
Benchmark.ips do |x|
|
12
|
-
x.time =
|
13
|
-
x.warmup =
|
12
|
+
x.time = 30
|
13
|
+
x.warmup = 5
|
14
14
|
|
15
15
|
x.report('stdlib CSV') { CSV.parse(csv) }
|
16
16
|
x.report('HoneyFormat::CSV') { HoneyFormat::CSV.new(csv).rows }
|
data/honey_format.gemspec
CHANGED
data/lib/honey_format/csv.rb
CHANGED
@@ -17,9 +17,9 @@ module HoneyFormat
|
|
17
17
|
# @raise [UnknownCSVHeaderColumnError] raised when column is not in valid list.
|
18
18
|
def initialize(csv, delimiter: ',', header: nil, valid_columns: :all, header_converter: ConvertHeaderValue, row_builder: nil)
|
19
19
|
csv = ::CSV.parse(csv, col_sep: delimiter)
|
20
|
-
|
21
|
-
@header = Header.new(
|
22
|
-
@
|
20
|
+
header_row = header || csv.shift
|
21
|
+
@header = Header.new(header_row, valid: valid_columns, converter: header_converter)
|
22
|
+
@rows = Rows.new(csv, columns, builder: row_builder)
|
23
23
|
end
|
24
24
|
|
25
25
|
# @return [Array] of strings for sanitized header.
|
@@ -35,12 +35,17 @@ module HoneyFormat
|
|
35
35
|
# @return [Array] of rows.
|
36
36
|
# @raise [InvalidRowLengthError] raised when there are more row elements longer than columns
|
37
37
|
def rows
|
38
|
-
@rows
|
38
|
+
@rows
|
39
39
|
end
|
40
40
|
|
41
41
|
# @yield [row] block to receive the row.
|
42
42
|
def each_row
|
43
43
|
rows.each { |row| yield(row) }
|
44
44
|
end
|
45
|
+
|
46
|
+
# @return [String] CSV-string representation.
|
47
|
+
def to_csv
|
48
|
+
header.to_csv + @rows.to_csv
|
49
|
+
end
|
45
50
|
end
|
46
51
|
end
|
data/lib/honey_format/header.rb
CHANGED
data/lib/honey_format/row.rb
CHANGED
@@ -1,15 +1,12 @@
|
|
1
|
+
require 'honey_format/row_builder'
|
2
|
+
|
1
3
|
module HoneyFormat
|
2
4
|
# Holds data for a single row.
|
3
5
|
class Row
|
4
|
-
class RowBuilder < Struct
|
5
|
-
def self.call(row)
|
6
|
-
new(*row)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
6
|
# Returns a new instance of Row.
|
11
7
|
# @return [Row] a new instance of Row.
|
12
8
|
# @param [Array] columns an array of symbols.
|
9
|
+
# @param builder [#call, #to_csv] optional row builder
|
13
10
|
# @raise [EmptyColumnsError] raised when there are no columns.
|
14
11
|
# @example Create new row
|
15
12
|
# Row.new!([:id])
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module HoneyFormat
|
2
|
+
# Default row builder
|
3
|
+
class RowBuilder < Struct
|
4
|
+
# @return [Struct] returns an instantiated Struct representing a row
|
5
|
+
def self.call(row)
|
6
|
+
new(*row)
|
7
|
+
end
|
8
|
+
|
9
|
+
# @return [String] CSV-string representation.
|
10
|
+
def to_csv
|
11
|
+
members.map do |column_name|
|
12
|
+
column = public_send(column_name)
|
13
|
+
if column.respond_to?(:to_csv)
|
14
|
+
column.to_csv
|
15
|
+
else
|
16
|
+
column.to_s
|
17
|
+
end
|
18
|
+
end.join(',') + "\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/honey_format/rows.rb
CHANGED
@@ -3,6 +3,8 @@ require 'honey_format/row'
|
|
3
3
|
module HoneyFormat
|
4
4
|
# Represents rows.
|
5
5
|
class Rows
|
6
|
+
include Enumerable
|
7
|
+
|
6
8
|
# Returns array of cleaned strings.
|
7
9
|
# @return [Rows] new instance of Rows.
|
8
10
|
# @param [Array] rows the array of rows.
|
@@ -11,12 +13,25 @@ module HoneyFormat
|
|
11
13
|
@rows = prepare_rows(Row.new(columns, builder: builder), rows)
|
12
14
|
end
|
13
15
|
|
16
|
+
# @yield [row] The given block will be passed every row.
|
17
|
+
# @yieldparam [Row] a row in the CSV file.
|
18
|
+
# @return [Enumerator]
|
19
|
+
# If no block is given, an enumerator object will be returned.
|
20
|
+
def each(&block)
|
21
|
+
@rows.each(&block)
|
22
|
+
end
|
23
|
+
|
14
24
|
# Returns rows as array.
|
15
25
|
# @return [Array] of rows.
|
16
26
|
def to_a
|
17
27
|
@rows
|
18
28
|
end
|
19
29
|
|
30
|
+
# @return [String] CSV-string representation.
|
31
|
+
def to_csv
|
32
|
+
to_a.map(&:to_csv).join
|
33
|
+
end
|
34
|
+
|
20
35
|
private
|
21
36
|
|
22
37
|
def prepare_rows(builder, rows)
|
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.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Burenstam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: byebug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
description: Convert CSV to an array of objects with with ease. Create objects for
|
84
98
|
each row with methods matching the column names. No dependencies other than Ruby
|
85
99
|
stdlib.
|
@@ -109,6 +123,7 @@ files:
|
|
109
123
|
- lib/honey_format/exceptions.rb
|
110
124
|
- lib/honey_format/header.rb
|
111
125
|
- lib/honey_format/row.rb
|
126
|
+
- lib/honey_format/row_builder.rb
|
112
127
|
- lib/honey_format/rows.rb
|
113
128
|
- lib/honey_format/sanitize.rb
|
114
129
|
- lib/honey_format/version.rb
|