table_structure 0.1.2 → 0.1.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.
- checksums.yaml +4 -4
- data/Gemfile +4 -2
- data/Gemfile.lock +17 -1
- data/README.md +15 -5
- data/Rakefile +5 -3
- data/bin/console +4 -3
- data/lib/table_structure.rb +2 -1
- data/lib/table_structure/schema.rb +2 -0
- data/lib/table_structure/schema/column.rb +36 -32
- data/lib/table_structure/schema/dsl/column_converter.rb +3 -1
- data/lib/table_structure/schema/dsl/column_definition.rb +3 -1
- data/lib/table_structure/schema/dsl/context_builder.rb +3 -1
- data/lib/table_structure/schema/dsl/result_builder.rb +3 -1
- data/lib/table_structure/schema/table.rb +34 -34
- data/lib/table_structure/schema/utils.rb +3 -1
- data/lib/table_structure/version.rb +3 -1
- data/lib/table_structure/writer.rb +10 -9
- data/table_structure.gemspec +17 -15
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a208013676cd213826e9c8f6fd29ef6e364bd321f198a3f87424806c79d87b8
|
4
|
+
data.tar.gz: 4eda6349d9ab15a2d8183ec27678d19bcef4750376e2981e9feb15cf4d93d844
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d903f50237ef4323d81fbec517a3c9206a444fc14063e5aa12e4696fa361419f8955bebb0c5e74c77398db8b8ec7a5dcb871487752ad65344b0bcfedb334b7d1
|
7
|
+
data.tar.gz: 38de89299ff6745eb8ad32e12d8e64b081d36d6d510ef8e429b5189ec7bfabd33ce06768f08454e3e7cf576244ebb981506161e580440c7a010ef52eb3cd28cf
|
data/Gemfile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
6
|
|
5
7
|
# Specify your gem's dependencies in table_structure.gemspec
|
6
8
|
gemspec
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
table_structure (0.1.
|
4
|
+
table_structure (0.1.3)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
ast (2.4.0)
|
9
10
|
diff-lcs (1.3)
|
11
|
+
jaro_winkler (1.5.3)
|
12
|
+
parallel (1.17.0)
|
13
|
+
parser (2.6.3.0)
|
14
|
+
ast (~> 2.4.0)
|
15
|
+
rainbow (3.0.0)
|
10
16
|
rake (10.5.0)
|
11
17
|
rspec (3.8.0)
|
12
18
|
rspec-core (~> 3.8.0)
|
@@ -21,6 +27,15 @@ GEM
|
|
21
27
|
diff-lcs (>= 1.2.0, < 2.0)
|
22
28
|
rspec-support (~> 3.8.0)
|
23
29
|
rspec-support (3.8.2)
|
30
|
+
rubocop (0.74.0)
|
31
|
+
jaro_winkler (~> 1.5.1)
|
32
|
+
parallel (~> 1.10)
|
33
|
+
parser (>= 2.6)
|
34
|
+
rainbow (>= 2.2.2, < 4.0)
|
35
|
+
ruby-progressbar (~> 1.7)
|
36
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
37
|
+
ruby-progressbar (1.10.1)
|
38
|
+
unicode-display_width (1.6.0)
|
24
39
|
|
25
40
|
PLATFORMS
|
26
41
|
ruby
|
@@ -29,6 +44,7 @@ DEPENDENCIES
|
|
29
44
|
bundler (~> 1.17)
|
30
45
|
rake (~> 10.0)
|
31
46
|
rspec (~> 3.0)
|
47
|
+
rubocop (~> 0.74.0)
|
32
48
|
table_structure!
|
33
49
|
|
34
50
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -39,14 +39,14 @@ class SampleTableSchema
|
|
39
39
|
columns name: ['Pet 1', 'Pet 2', 'Pet 3'],
|
40
40
|
value: ->(row, *) { row[:pets] }
|
41
41
|
|
42
|
-
columns ->(table)
|
42
|
+
columns ->(table) {
|
43
43
|
table[:questions].map do |question|
|
44
44
|
{
|
45
45
|
name: question[:id],
|
46
46
|
value: ->(row, *) { row[:answers][question[:id]] }
|
47
47
|
}
|
48
48
|
end
|
49
|
-
|
49
|
+
}
|
50
50
|
|
51
51
|
column_converter :to_s, ->(val, _row, _table) { val.to_s }
|
52
52
|
end
|
@@ -126,7 +126,7 @@ class SampleTableSchema
|
|
126
126
|
context_builder :row, ->(context) { RowContext.new(**context) }
|
127
127
|
|
128
128
|
column name: 'ID',
|
129
|
-
value: ->(row,
|
129
|
+
value: ->(row, *) { row.id }
|
130
130
|
|
131
131
|
column name: 'Name',
|
132
132
|
value: ->(row, *) { row.name }
|
@@ -134,14 +134,14 @@ class SampleTableSchema
|
|
134
134
|
columns name: ['Pet 1', 'Pet 2', 'Pet 3'],
|
135
135
|
value: ->(row, *) { row.more_pets }
|
136
136
|
|
137
|
-
columns ->(table)
|
137
|
+
columns ->(table) {
|
138
138
|
table.questions.map do |question|
|
139
139
|
{
|
140
140
|
name: question[:id],
|
141
141
|
value: ->(row, *) { row.answers[question[:id]] }
|
142
142
|
}
|
143
143
|
end
|
144
|
-
|
144
|
+
}
|
145
145
|
|
146
146
|
column_converter :to_s, ->(val, *) { val.to_s }
|
147
147
|
end
|
@@ -156,6 +156,16 @@ File.open('sample.csv', 'w') do |f|
|
|
156
156
|
end
|
157
157
|
```
|
158
158
|
|
159
|
+
You can also use only `TableStructure::Schema`.
|
160
|
+
```ruby
|
161
|
+
schema = SampleTableSchema.new
|
162
|
+
header = schema.header
|
163
|
+
items.each do |item|
|
164
|
+
row = schema.row(context: item)
|
165
|
+
...
|
166
|
+
end
|
167
|
+
```
|
168
|
+
|
159
169
|
## Contributing
|
160
170
|
|
161
171
|
Bug reports and pull requests are welcome on GitHub at https://github.com/jsmmr/ruby_table_structure.
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'table_structure'
|
5
6
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +11,5 @@ require "table_structure"
|
|
10
11
|
# require "pry"
|
11
12
|
# Pry.start
|
12
13
|
|
13
|
-
require
|
14
|
+
require 'irb'
|
14
15
|
IRB.start(__FILE__)
|
data/lib/table_structure.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TableStructure
|
2
4
|
class Error < StandardError; end
|
3
5
|
|
@@ -12,5 +14,4 @@ module TableStructure
|
|
12
14
|
require 'table_structure/schema/column'
|
13
15
|
require 'table_structure/schema/utils'
|
14
16
|
require 'table_structure/writer'
|
15
|
-
|
16
17
|
end
|
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TableStructure
|
2
4
|
module Schema
|
3
5
|
class Column
|
4
|
-
|
5
6
|
class Error < ::TableStructure::Error
|
6
7
|
attr_reader :group_index
|
7
8
|
|
@@ -16,7 +17,7 @@ module TableStructure
|
|
16
17
|
key: nil,
|
17
18
|
value: nil,
|
18
19
|
size: nil
|
19
|
-
}
|
20
|
+
}.freeze
|
20
21
|
|
21
22
|
DEFAULT_SIZE = 1
|
22
23
|
|
@@ -48,43 +49,46 @@ module TableStructure
|
|
48
49
|
|
49
50
|
private
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
if size && size < DEFAULT_SIZE
|
56
|
-
raise Error.new('"size" must be positive.', @group_index)
|
57
|
-
end
|
52
|
+
def validate(name:, key:, size:, **)
|
53
|
+
if !key && name.respond_to?(:call) && !size
|
54
|
+
raise Error.new('"size" must be specified, because column size cannot be determined.', @group_index)
|
58
55
|
end
|
59
|
-
|
60
|
-
|
61
|
-
return size if size
|
62
|
-
[calculate_size(name), calculate_size(key)].max
|
56
|
+
if size && size < DEFAULT_SIZE
|
57
|
+
raise Error.new('"size" must be positive.', @group_index)
|
63
58
|
end
|
59
|
+
end
|
64
60
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
61
|
+
def determine_size(name:, key:, size:, **)
|
62
|
+
return size if size
|
63
|
+
|
64
|
+
[calculate_size(name), calculate_size(key)].max
|
65
|
+
end
|
71
66
|
|
72
|
-
|
73
|
-
|
67
|
+
def calculate_size(val)
|
68
|
+
if val.is_a?(Array)
|
69
|
+
return val.empty? ? DEFAULT_SIZE : val.size
|
74
70
|
end
|
75
71
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
72
|
+
DEFAULT_SIZE
|
73
|
+
end
|
74
|
+
|
75
|
+
def multiple?
|
76
|
+
@size > DEFAULT_SIZE
|
77
|
+
end
|
78
|
+
|
79
|
+
def optimize_size(value)
|
80
|
+
return value unless multiple?
|
81
|
+
|
82
|
+
values = value.is_a?(Array) ? value : [value]
|
83
|
+
actual_size = values.size
|
84
|
+
if actual_size > @size
|
85
|
+
values[0, @size]
|
86
|
+
elsif actual_size < @size
|
87
|
+
[].concat(values).fill(nil, actual_size, (@size - actual_size))
|
88
|
+
else
|
89
|
+
values
|
87
90
|
end
|
91
|
+
end
|
88
92
|
end
|
89
93
|
end
|
90
94
|
end
|
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TableStructure
|
2
4
|
module Schema
|
3
5
|
class Table
|
4
|
-
|
5
|
-
DEFAULT_OPTIONS = { result_type: :array }
|
6
|
+
DEFAULT_OPTIONS = { result_type: :array }.freeze
|
6
7
|
|
7
8
|
attr_reader :columns, :column_converters, :result_builders
|
8
9
|
|
@@ -24,45 +25,44 @@ module TableStructure
|
|
24
25
|
|
25
26
|
private
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
.flatten
|
33
|
-
.map { |definition| Column.new(definition, i) }
|
34
|
-
end
|
28
|
+
def build_columns(definitions)
|
29
|
+
definitions
|
30
|
+
.map { |definition| Utils.evaluate_callable(definition, @context) }
|
31
|
+
.map.with_index do |definition, i|
|
32
|
+
[definition]
|
35
33
|
.flatten
|
36
|
-
|
37
|
-
|
38
|
-
def default_column_converters
|
39
|
-
{}
|
40
|
-
end
|
41
|
-
|
42
|
-
def default_result_builders
|
43
|
-
result_builders = {}
|
44
|
-
if @options[:result_type] == :hash
|
45
|
-
result_builders[:to_h] = ->(array, *) { (@keys ||= keys).zip(array).to_h }
|
34
|
+
.map { |definition| Column.new(definition, i) }
|
46
35
|
end
|
47
|
-
|
48
|
-
|
36
|
+
.flatten
|
37
|
+
end
|
49
38
|
|
50
|
-
|
51
|
-
|
52
|
-
|
39
|
+
def default_column_converters
|
40
|
+
{}
|
41
|
+
end
|
53
42
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
.map { |val| reduce_callables(@column_converters, val, context) }
|
59
|
-
reduce_callables(@result_builders, columns, context)
|
43
|
+
def default_result_builders
|
44
|
+
result_builders = {}
|
45
|
+
if @options[:result_type] == :hash
|
46
|
+
result_builders[:to_h] = ->(array, *) { (@keys ||= keys).zip(array).to_h }
|
60
47
|
end
|
48
|
+
result_builders
|
49
|
+
end
|
61
50
|
|
62
|
-
|
63
|
-
|
64
|
-
|
51
|
+
def keys
|
52
|
+
@columns.map(&:key).flatten
|
53
|
+
end
|
54
|
+
|
55
|
+
def values(method, context)
|
56
|
+
columns = @columns
|
57
|
+
.map { |column| column.send(method, context, @context) }
|
58
|
+
.flatten
|
59
|
+
.map { |val| reduce_callables(@column_converters, val, context) }
|
60
|
+
reduce_callables(@result_builders, columns, context)
|
61
|
+
end
|
65
62
|
|
63
|
+
def reduce_callables(callables, val, context)
|
64
|
+
callables.reduce(val) { |val, (_, callable)| callable.call(val, context, @context) }
|
65
|
+
end
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -1,11 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TableStructure
|
2
4
|
class Writer
|
3
|
-
|
4
5
|
DEFAULT_OPTIONS = {
|
5
6
|
header_omitted: false,
|
6
7
|
header_context: nil,
|
7
8
|
method: :<<
|
8
|
-
}
|
9
|
+
}.freeze
|
9
10
|
|
10
11
|
def initialize(schema, **options)
|
11
12
|
@schema = schema
|
@@ -19,20 +20,20 @@ module TableStructure
|
|
19
20
|
header = yield header if block_given?
|
20
21
|
to.send(options[:method], header)
|
21
22
|
end
|
22
|
-
|
23
|
+
enumerize(items).each do |item|
|
23
24
|
row = @schema.row(context: item)
|
24
25
|
row = yield row if block_given?
|
25
26
|
to.send(options[:method], row)
|
26
27
|
end
|
27
|
-
|
28
|
+
nil
|
28
29
|
end
|
29
30
|
|
30
31
|
private
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
def enumerize(items)
|
34
|
+
items.respond_to?(:call) ?
|
35
|
+
Enumerator.new { |y| items.call(y) } :
|
36
|
+
items
|
37
|
+
end
|
37
38
|
end
|
38
39
|
end
|
data/table_structure.gemspec
CHANGED
@@ -1,29 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
|
-
lib = File.expand_path(
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require 'table_structure/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = 'table_structure'
|
8
9
|
spec.version = TableStructure::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
10
|
+
spec.authors = ['jsmmr']
|
11
|
+
spec.email = ['jsmmr@icloud.com']
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
13
|
+
spec.summary = 'Create and output table structure data.'
|
14
|
+
spec.description = 'This gem creates and outputs table structure data. Useful for creating CSV.'
|
15
|
+
spec.homepage = 'https://github.com/jsmmr/ruby_table_structure'
|
16
|
+
spec.license = 'MIT'
|
16
17
|
|
17
18
|
# Specify which files should be added to the gem when it is released.
|
18
19
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
19
|
-
spec.files = Dir.chdir(File.expand_path(
|
20
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
20
21
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
21
22
|
end
|
22
|
-
spec.bindir =
|
23
|
+
spec.bindir = 'exe'
|
23
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
-
spec.require_paths = [
|
25
|
+
spec.require_paths = ['lib']
|
25
26
|
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.17'
|
28
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
29
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
30
|
+
spec.add_development_dependency 'rubocop', '~> 0.74.0'
|
29
31
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: table_structure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jsmmr
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.74.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.74.0
|
55
69
|
description: This gem creates and outputs table structure data. Useful for creating
|
56
70
|
CSV.
|
57
71
|
email:
|