honey_format 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/.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
|