table_structure 0.3.22 → 0.4.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +33 -0
  4. data/Gemfile.lock +7 -7
  5. data/README.md +30 -31
  6. data/lib/table_structure.rb +6 -12
  7. data/lib/table_structure/csv/writer.rb +4 -41
  8. data/lib/table_structure/iterator.rb +48 -89
  9. data/lib/table_structure/schema.rb +63 -76
  10. data/lib/table_structure/schema/class_methods.rb +9 -28
  11. data/lib/table_structure/schema/column_builder_factory.rb +75 -0
  12. data/lib/table_structure/schema/columns/attributes.rb +14 -9
  13. data/lib/table_structure/schema/columns/schema.rb +14 -9
  14. data/lib/table_structure/schema/composite_class.rb +40 -0
  15. data/lib/table_structure/schema/definition/columns/compiler.rb +7 -3
  16. data/lib/table_structure/schema/definition/columns/validator.rb +2 -6
  17. data/lib/table_structure/schema/dsl/column_builder.rb +29 -0
  18. data/lib/table_structure/schema/dsl/column_definition.rb +12 -2
  19. data/lib/table_structure/schema/dsl/context_builder.rb +2 -11
  20. data/lib/table_structure/schema/dsl/row_builder.rb +2 -9
  21. data/lib/table_structure/schema/{key_converter.rb → keys_builder.rb} +2 -2
  22. data/lib/table_structure/schema/row_context_builder_factory.rb +26 -0
  23. data/lib/table_structure/table.rb +31 -56
  24. data/lib/table_structure/utils.rb +40 -0
  25. data/lib/table_structure/version.rb +1 -1
  26. data/lib/table_structure/writer.rb +7 -54
  27. metadata +8 -14
  28. data/lib/table_structure/schema/column_converter.rb +0 -46
  29. data/lib/table_structure/schema/definition/column_converter.rb +0 -31
  30. data/lib/table_structure/schema/definition/context_builder.rb +0 -17
  31. data/lib/table_structure/schema/definition/row_builder.rb +0 -25
  32. data/lib/table_structure/schema/dsl/column_converter.rb +0 -41
  33. data/lib/table_structure/schema/dsl/option.rb +0 -19
  34. data/lib/table_structure/schema/row_builder.rb +0 -21
  35. data/lib/table_structure/table/column_converter.rb +0 -46
  36. data/lib/table_structure/table/context_builder.rb +0 -49
  37. data/lib/table_structure/table/iterator.rb +0 -22
  38. data/lib/table_structure/table/row_builder.rb +0 -38
@@ -13,15 +13,11 @@ module TableStructure
13
13
  end
14
14
 
15
15
  def validate(name:, key:, size:, **)
16
- if key.respond_to?(:call)
17
- raise Error.new('"key" must not be lambda.', @name, @index)
18
- end
16
+ raise Error.new('"key" must not be callable.', @name, @index) if key.respond_to?(:call)
19
17
  if !key && name.respond_to?(:call) && !size
20
18
  raise Error.new('"size" must be defined, because column size cannot be determined.', @name, @index)
21
19
  end
22
- if size && size < DEFAULT_SIZE
23
- raise Error.new('"size" must be positive.', @name, @index)
24
- end
20
+ raise Error.new('"size" must be positive.', @name, @index) if size && size < DEFAULT_SIZE
25
21
  if key && size && [key].flatten.size < size
26
22
  raise Error.new('"key" size must not be less than specified "size".', @name, @index)
27
23
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ module DSL
6
+ module ColumnBuilder
7
+ def column_builder(
8
+ name,
9
+ header: true,
10
+ body: true,
11
+ &block
12
+ )
13
+ column_builders[name] =
14
+ ::TableStructure::Utils::TypedProc.new(
15
+ types: { header: !!header, body: !!body }.select { |_k, v| v }.keys,
16
+ &block
17
+ )
18
+ nil
19
+ end
20
+
21
+ def column_builders
22
+ @__column_builders__ ||= {}
23
+ end
24
+
25
+ alias column_converter column_builder
26
+ end
27
+ end
28
+ end
29
+ end
@@ -5,12 +5,22 @@ module TableStructure
5
5
  module DSL
6
6
  module ColumnDefinition
7
7
  def column(definition)
8
+ unless definition.is_a?(Hash)
9
+ warn "[TableStructure] Use `columns` instead of `column`.", uplevel: 1
10
+ end
8
11
  column_definitions << definition
9
12
  nil
10
13
  end
11
14
 
12
- def columns(definition)
13
- column(definition)
15
+ def columns(definition = nil, &block)
16
+ if definition.is_a?(Hash)
17
+ warn "[TableStructure] Use `column` instead of `columns`.", uplevel: 1
18
+ end
19
+ if Utils.callable?(definition)
20
+ warn "[TableStructure] Use `block` instead of `lambda` or `proc`.", uplevel: 1
21
+ end
22
+ column_definitions << (block || definition)
23
+ nil
14
24
  end
15
25
 
16
26
  def column_definitions
@@ -5,17 +5,8 @@ module TableStructure
5
5
  module DSL
6
6
  module ContextBuilder
7
7
  # TODO: Change definition style
8
- def context_builder(name, callable = nil, &block)
9
- if callable
10
- warn "[TableStructure] Use `block` instead of #{callable}."
11
- end
12
-
13
- block ||= callable
14
-
15
- context_builders[name] =
16
- ::TableStructure::Schema::Definition::ContextBuilder.new(
17
- &block
18
- )
8
+ def context_builder(name, &block)
9
+ context_builders[name] = block
19
10
  nil
20
11
  end
21
12
 
@@ -6,19 +6,12 @@ module TableStructure
6
6
  module RowBuilder
7
7
  def row_builder(
8
8
  name,
9
- callable = nil,
10
9
  enabled_row_types: %i[array hash],
11
10
  &block
12
11
  )
13
- if callable
14
- warn "[TableStructure] Use `block` instead of #{callable}."
15
- end
16
-
17
- block ||= callable
18
-
19
12
  row_builders[name] =
20
- ::TableStructure::Schema::Definition::RowBuilder.new(
21
- enabled_row_types: enabled_row_types,
13
+ ::TableStructure::Utils::TypedProc.new(
14
+ types: enabled_row_types,
22
15
  &block
23
16
  )
24
17
  nil
@@ -2,13 +2,13 @@
2
2
 
3
3
  module TableStructure
4
4
  module Schema
5
- class KeyConverter
5
+ class KeysBuilder
6
6
  def initialize(prefix: nil, suffix: nil)
7
7
  @prefix = prefix
8
8
  @suffix = suffix
9
9
  end
10
10
 
11
- def convert(keys)
11
+ def build(keys)
12
12
  return keys unless has_any_options?
13
13
 
14
14
  keys.map do |key|
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ class RowContextBuilderFactory
6
+ def initialize(schema, builders)
7
+ @schema = schema
8
+ @builders = builders
9
+ end
10
+
11
+ def create_header_builder
12
+ return unless @schema.contain_name_callable?
13
+ return unless @builders.key?(:header)
14
+
15
+ proc { |context| @builders[:header].call(context) }
16
+ end
17
+
18
+ def create_data_builder
19
+ return unless @schema.contain_value_callable?
20
+ return unless @builders.key?(:row)
21
+
22
+ proc { |context| @builders[:row].call(context) }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -2,71 +2,46 @@
2
2
 
3
3
  module TableStructure
4
4
  class Table
5
- def initialize(schema, row_type: :array)
6
- @columns = schema.columns
7
- @context = schema.context
8
- @key_converter = schema.key_converter
9
-
10
- ContextBuilder.create_module(
11
- schema.context_builders,
12
- apply_to_name: schema.contain_callable?(:name),
13
- apply_to_value: schema.contain_callable?(:value),
14
- context: schema.context
15
- ) { |mod| extend mod }
16
-
17
- ColumnConverter.create_module(
18
- schema.column_converters,
19
- context: schema.context
20
- ) { |mod| extend mod }
5
+ DEFAULT_ROW_BUILDERS = {
6
+ _to_hash_: Utils::TypedProc.new(
7
+ types: :hash
8
+ ) do |values, keys|
9
+ keys.map.with_index { |key, i| [key || i, values[i]] }.to_h
10
+ end
11
+ }.freeze
21
12
 
22
- RowBuilder.create_module(
23
- schema.row_builders,
24
- row_type: row_type,
25
- keys: keys,
26
- context: schema.context
27
- ) { |mod| extend mod }
13
+ def initialize(schema, row_type: :array)
14
+ @header_row_generator = schema.create_header_row_generator
15
+ @data_row_generator = schema.create_data_row_generator
16
+
17
+ row_builders =
18
+ DEFAULT_ROW_BUILDERS
19
+ .merge(schema.row_builders)
20
+ .select { |_k, v| v.typed?(row_type) }
21
+ .values
22
+
23
+ unless row_builders.empty?
24
+ row_build_task = proc do |row|
25
+ row.values = row_builders.reduce(row.values) do |values, builder|
26
+ builder.call(values, row.keys, row.context, schema.context)
27
+ end
28
+ row
29
+ end
30
+ @header_row_generator.compose(row_build_task)
31
+ @data_row_generator.compose(row_build_task)
32
+ end
28
33
 
29
34
  yield self if block_given?
30
35
  end
31
36
 
32
37
  def header(context: nil)
33
- row_values(:names, context)
38
+ @header_row_generator.call(context).values
34
39
  end
35
40
 
36
- def body(items)
37
- Enumerator.new do |y|
38
- items.each { |item| y << data(context: item) }
41
+ def body(contexts)
42
+ ::Enumerator.new do |y|
43
+ contexts.each { |context| y << @data_row_generator.call(context).values }
39
44
  end
40
45
  end
41
-
42
- def rows(items)
43
- warn '[TableStructure] `TableStructure::Table#rows(items)` has been deprecated. Use `TableStructure::Table#body(items)` instead.'
44
- body(items)
45
- end
46
-
47
- def row(context: nil)
48
- warn '[TableStructure] `TableStructure::Table#row(context: ...)` has been deprecated. Use `TableStructure::Table#body(items)` instead.'
49
- data(context: context)
50
- end
51
-
52
- private
53
-
54
- def data(context: nil)
55
- row_values(:values, context)
56
- end
57
-
58
- def keys
59
- @keys ||= @key_converter.convert(@columns.map(&:keys).flatten)
60
- end
61
-
62
- def size
63
- @size ||= @columns.map(&:size).reduce(0, &:+)
64
- end
65
-
66
- def row_values(method, context)
67
- @columns
68
- .map { |column| column.send(method, context, @context) }
69
- .flatten
70
- end
71
46
  end
72
47
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Utils
5
+ class Proc < ::Proc
6
+ attr_reader :options
7
+
8
+ def initialize(**options, &block)
9
+ @options = options
10
+ super(&block)
11
+ end
12
+ end
13
+
14
+ class TypedProc < Proc
15
+ def initialize(types:, **options, &block)
16
+ @types = [types].flatten.compact
17
+ super(**options, &block)
18
+ end
19
+
20
+ def typed?(type)
21
+ @types.include?(type)
22
+ end
23
+ end
24
+
25
+ class CompositeCallable
26
+ def initialize
27
+ @callables = []
28
+ end
29
+
30
+ def compose(*callables)
31
+ @callables.concat(callables.flatten.compact)
32
+ self
33
+ end
34
+
35
+ def call(source)
36
+ @callables.reduce(source) { |memo, callable| callable.call(memo) }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TableStructure
4
- VERSION = '0.3.22'
4
+ VERSION = '0.4.3'
5
5
  end
@@ -4,28 +4,10 @@ module TableStructure
4
4
  class Writer
5
5
  def initialize(
6
6
  schema,
7
- header: { context: nil },
7
+ header: { context: nil, step: nil },
8
8
  method: :<<,
9
- row_type: :array,
10
- **deprecated_options
9
+ row_type: :array
11
10
  )
12
- if deprecated_options.key?(:header_omitted)
13
- header_omitted = deprecated_options[:header_omitted]
14
- warn "[TableStructure] `header_omitted: #{!!header_omitted}` option has been deprecated. Use `header: #{!header_omitted}` option instead."
15
- header = !header_omitted
16
- end
17
-
18
- if deprecated_options.key?(:header_context)
19
- header_context = deprecated_options[:header_context]
20
- warn '[TableStructure] `:header_context` option has been deprecated. Use `header: { context: ... }` option instead.'
21
- header = { context: header_context }
22
- end
23
-
24
- if deprecated_options.key?(:result_type)
25
- warn '[TableStructure] `:result_type` option has been deprecated. Use `:row_type` option instead.'
26
- row_type = deprecated_options[:result_type]
27
- end
28
-
29
11
  @schema = schema
30
12
  @options = {
31
13
  header: header,
@@ -38,51 +20,22 @@ module TableStructure
38
20
  items,
39
21
  to:,
40
22
  method: @options[:method],
41
- **deprecated_options,
42
23
  &block
43
24
  )
44
- header = @options[:header]
45
- row_type = @options[:row_type]
46
-
47
- if deprecated_options.key?(:header)
48
- header = deprecated_options[:header]
49
- warn '[TableStructure] Use :header option on initialize method.'
50
- end
51
-
52
- if deprecated_options.key?(:header_omitted)
53
- header_omitted = deprecated_options[:header_omitted]
54
- warn "[TableStructure] `header_omitted: #{!!header_omitted}` option has been deprecated. Use `header: #{!header_omitted}` option instead."
55
- header = !header_omitted
56
- end
57
-
58
- if deprecated_options.key?(:header_context)
59
- header_context = deprecated_options[:header_context]
60
- warn '[TableStructure] `:header_context` option has been deprecated. Use `header: { context: ... }` option instead.'
61
- header = { context: header_context }
62
- end
63
-
64
- if deprecated_options.key?(:row_type)
65
- row_type = deprecated_options[:row_type]
66
- warn '[TableStructure] Use :row_type option on initialize method.'
67
- end
68
-
69
- if deprecated_options.key?(:result_type)
70
- warn '[TableStructure] `:result_type` option has been deprecated. Use `:row_type` option instead.'
71
- row_type = deprecated_options[:result_type]
72
- end
73
-
74
25
  output = Output.new(to, method: method)
75
26
 
76
27
  Iterator
77
- .new(@schema, header: header, row_type: row_type)
28
+ .new(
29
+ @schema,
30
+ header: @options[:header],
31
+ row_type: @options[:row_type]
32
+ )
78
33
  .iterate(items, &block)
79
34
  .each { |row| output.write(row) }
80
35
 
81
36
  nil
82
37
  end
83
38
 
84
- private
85
-
86
39
  class Output
87
40
  def initialize(output, method: :<<)
88
41
  @output = output
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.3.22
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - jsmmr
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-29 00:00:00.000000000 Z
11
+ date: 2020-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,31 +75,25 @@ files:
75
75
  - lib/table_structure/iterator.rb
76
76
  - lib/table_structure/schema.rb
77
77
  - lib/table_structure/schema/class_methods.rb
78
- - lib/table_structure/schema/column_converter.rb
78
+ - lib/table_structure/schema/column_builder_factory.rb
79
79
  - lib/table_structure/schema/columns/attributes.rb
80
80
  - lib/table_structure/schema/columns/schema.rb
81
- - lib/table_structure/schema/definition/column_converter.rb
81
+ - lib/table_structure/schema/composite_class.rb
82
82
  - lib/table_structure/schema/definition/columns/attributes.rb
83
83
  - lib/table_structure/schema/definition/columns/compiler.rb
84
84
  - lib/table_structure/schema/definition/columns/error.rb
85
85
  - lib/table_structure/schema/definition/columns/schema_class.rb
86
86
  - lib/table_structure/schema/definition/columns/schema_instance.rb
87
87
  - lib/table_structure/schema/definition/columns/validator.rb
88
- - lib/table_structure/schema/definition/context_builder.rb
89
- - lib/table_structure/schema/definition/row_builder.rb
90
- - lib/table_structure/schema/dsl/column_converter.rb
88
+ - lib/table_structure/schema/dsl/column_builder.rb
91
89
  - lib/table_structure/schema/dsl/column_definition.rb
92
90
  - lib/table_structure/schema/dsl/context_builder.rb
93
- - lib/table_structure/schema/dsl/option.rb
94
91
  - lib/table_structure/schema/dsl/row_builder.rb
95
- - lib/table_structure/schema/key_converter.rb
96
- - lib/table_structure/schema/row_builder.rb
92
+ - lib/table_structure/schema/keys_builder.rb
93
+ - lib/table_structure/schema/row_context_builder_factory.rb
97
94
  - lib/table_structure/schema/utils.rb
98
95
  - lib/table_structure/table.rb
99
- - lib/table_structure/table/column_converter.rb
100
- - lib/table_structure/table/context_builder.rb
101
- - lib/table_structure/table/iterator.rb
102
- - lib/table_structure/table/row_builder.rb
96
+ - lib/table_structure/utils.rb
103
97
  - lib/table_structure/version.rb
104
98
  - lib/table_structure/writer.rb
105
99
  - table_structure.gemspec