table_structure 0.3.16 → 0.3.17

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -3
  3. data/Gemfile.lock +5 -5
  4. data/README.md +44 -38
  5. data/lib/table_structure.rb +15 -10
  6. data/lib/table_structure/schema.rb +43 -22
  7. data/lib/table_structure/schema/class_methods.rb +2 -2
  8. data/lib/table_structure/schema/column_converters.rb +40 -44
  9. data/lib/table_structure/schema/{column/attrs.rb → columns/attributes.rb} +7 -2
  10. data/lib/table_structure/schema/{column → columns}/schema.rb +6 -4
  11. data/lib/table_structure/schema/context_builders.rb +12 -4
  12. data/lib/table_structure/schema/definition/column_converter.rb +31 -0
  13. data/lib/table_structure/schema/definition/columns/attributes.rb +55 -0
  14. data/lib/table_structure/schema/definition/columns/compiler.rb +45 -0
  15. data/lib/table_structure/schema/{column/definition → definition/columns}/error.rb +2 -2
  16. data/lib/table_structure/schema/definition/columns/schema_class.rb +24 -0
  17. data/lib/table_structure/schema/definition/columns/schema_instance.rb +23 -0
  18. data/lib/table_structure/schema/{column/definition → definition/columns}/validator.rb +2 -2
  19. data/lib/table_structure/schema/definition/context_builder.rb +17 -0
  20. data/lib/table_structure/schema/definition/row_builder.rb +25 -0
  21. data/lib/table_structure/schema/dsl/column_converter.rb +16 -9
  22. data/lib/table_structure/schema/dsl/context_builder.rb +4 -1
  23. data/lib/table_structure/schema/dsl/row_builder.rb +26 -0
  24. data/lib/table_structure/schema/keys_generator.rb +29 -0
  25. data/lib/table_structure/schema/row_builders.rb +58 -0
  26. data/lib/table_structure/schema/table.rb +24 -16
  27. data/lib/table_structure/schema/utils.rb +5 -1
  28. data/lib/table_structure/version.rb +1 -1
  29. data/lib/table_structure/writer.rb +1 -1
  30. metadata +16 -11
  31. data/lib/table_structure/schema/column/definition/compiler.rb +0 -81
  32. data/lib/table_structure/schema/column/factory.rb +0 -22
  33. data/lib/table_structure/schema/dsl/result_builder.rb +0 -27
  34. data/lib/table_structure/schema/result_builders.rb +0 -67
  35. data/lib/table_structure/schema/table/key_decorator.rb +0 -32
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ class RowBuilders
6
+ DEFAULT_BUILDERS = {
7
+ _to_hash_: ::TableStructure::Schema::Definition::RowBuilder.new(
8
+ lambda { |values, keys, *|
9
+ keys.map.with_index { |key, i| [key || i, values[i]] }.to_h
10
+ },
11
+ enabled_row_types: [:hash]
12
+ )
13
+ }.freeze
14
+
15
+ def initialize(builders)
16
+ @builders = builders
17
+ end
18
+
19
+ def extend_methods_for(table, row_type: :array)
20
+ builders =
21
+ DEFAULT_BUILDERS
22
+ .merge(@builders)
23
+ .select { |_k, v| v.enabled?(row_type) }
24
+
25
+ return if builders.empty?
26
+
27
+ table_context = table.instance_variable_get(:@context)
28
+ table_keys = table.send(:keys)
29
+
30
+ table.extend ResultBuildable.new(
31
+ header: create_method(builders, table_keys, table_context),
32
+ data: create_method(builders, table_keys, table_context)
33
+ )
34
+ end
35
+
36
+ private
37
+
38
+ def create_method(builders, table_keys, table_context)
39
+ return if builders.empty?
40
+
41
+ proc do |context: nil|
42
+ builders
43
+ .reduce(super(context: context)) do |vals, (_, builder)|
44
+ builder.call(vals, table_keys, context, table_context)
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ class ResultBuildable < Module
51
+ def initialize(methods)
52
+ methods.each do |name, method|
53
+ define_method(name, &method)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -4,50 +4,58 @@ module TableStructure
4
4
  module Schema
5
5
  class Table
6
6
  def initialize(
7
- columns,
8
- context,
9
- options
7
+ columns:,
8
+ context:,
9
+ keys_generator:
10
10
  )
11
11
  @columns = columns
12
12
  @context = context
13
- @options = options
13
+ @keys_generator = keys_generator
14
14
  end
15
15
 
16
16
  def header(context: nil)
17
- values(:names, context)
17
+ row_values(:names, context)
18
18
  end
19
19
 
20
20
  def row(context: nil)
21
- values(:values, context)
21
+ warn '[TableStructure] `TableStructure::Schema::Table#row(context:)` has been deprecated. Use `TableStructure::Schema::Table#body(items)` instead.'
22
+ data(context: context)
22
23
  end
23
24
 
24
- def rows(items)
25
+ def body(items)
25
26
  Enumerator.new do |y|
26
- items.each { |item| y << row(context: item) }
27
+ items.each { |item| y << data(context: item) }
27
28
  end
28
29
  end
29
30
 
31
+ def rows(items)
32
+ warn '[TableStructure] `TableStructure::Schema::Table#rows(items)` has been deprecated. Use `TableStructure::Schema::Table#body(items)` instead.'
33
+ body(items)
34
+ end
35
+
30
36
  private
31
37
 
38
+ def data(context: nil)
39
+ row_values(:values, context)
40
+ end
41
+
32
42
  def keys
33
- @keys ||= begin
34
- keys = @columns.map(&:keys).flatten
35
- KeyDecorator.new(
36
- prefix: @options[:key_prefix],
37
- suffix: @options[:key_suffix]
38
- ).decorate(keys)
39
- end
43
+ @keys ||= @keys_generator.generate(@columns.map(&:keys).flatten)
40
44
  end
41
45
 
42
46
  def size
43
47
  @size ||= @columns.map(&:size).reduce(0, &:+)
44
48
  end
45
49
 
46
- def values(method, context)
50
+ def row_values(method, context)
47
51
  @columns
48
52
  .map { |column| column.send(method, context, @context) }
49
53
  .flatten
50
54
  end
55
+
56
+ def contain_callable?(attribute)
57
+ @columns.any? { |column| column.contain_callable?(attribute) }
58
+ end
51
59
  end
52
60
  end
53
61
  end
@@ -4,7 +4,11 @@ module TableStructure
4
4
  module Schema
5
5
  module Utils
6
6
  def self.evaluate_callable(val, *params)
7
- val.respond_to?(:call) ? val.call(*params) : val
7
+ callable?(val) ? val.call(*params) : val
8
+ end
9
+
10
+ def self.callable?(val)
11
+ val.respond_to?(:call)
8
12
  end
9
13
 
10
14
  def self.schema_class?(val)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TableStructure
4
- VERSION = '0.3.16'
4
+ VERSION = '0.3.17'
5
5
  end
@@ -23,7 +23,7 @@ module TableStructure
23
23
  header = yield header if block_given?
24
24
  to.send(options[:method], header)
25
25
  end
26
- table.rows(enumerize(items)).each do |row|
26
+ table.body(enumerize(items)).each do |row|
27
27
  row = yield row if block_given?
28
28
  to.send(options[:method], row)
29
29
  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.3.16
4
+ version: 0.3.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - jsmmr
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-31 00:00:00.000000000 Z
11
+ date: 2020-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,22 +75,27 @@ 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/attrs.rb
79
- - lib/table_structure/schema/column/definition/compiler.rb
80
- - lib/table_structure/schema/column/definition/error.rb
81
- - lib/table_structure/schema/column/definition/validator.rb
82
- - lib/table_structure/schema/column/factory.rb
83
- - lib/table_structure/schema/column/schema.rb
84
78
  - lib/table_structure/schema/column_converters.rb
79
+ - lib/table_structure/schema/columns/attributes.rb
80
+ - lib/table_structure/schema/columns/schema.rb
85
81
  - lib/table_structure/schema/context_builders.rb
82
+ - lib/table_structure/schema/definition/column_converter.rb
83
+ - lib/table_structure/schema/definition/columns/attributes.rb
84
+ - lib/table_structure/schema/definition/columns/compiler.rb
85
+ - lib/table_structure/schema/definition/columns/error.rb
86
+ - lib/table_structure/schema/definition/columns/schema_class.rb
87
+ - lib/table_structure/schema/definition/columns/schema_instance.rb
88
+ - lib/table_structure/schema/definition/columns/validator.rb
89
+ - lib/table_structure/schema/definition/context_builder.rb
90
+ - lib/table_structure/schema/definition/row_builder.rb
86
91
  - lib/table_structure/schema/dsl/column_converter.rb
87
92
  - lib/table_structure/schema/dsl/column_definition.rb
88
93
  - lib/table_structure/schema/dsl/context_builder.rb
89
94
  - lib/table_structure/schema/dsl/option.rb
90
- - lib/table_structure/schema/dsl/result_builder.rb
91
- - lib/table_structure/schema/result_builders.rb
95
+ - lib/table_structure/schema/dsl/row_builder.rb
96
+ - lib/table_structure/schema/keys_generator.rb
97
+ - lib/table_structure/schema/row_builders.rb
92
98
  - lib/table_structure/schema/table.rb
93
- - lib/table_structure/schema/table/key_decorator.rb
94
99
  - lib/table_structure/schema/utils.rb
95
100
  - lib/table_structure/version.rb
96
101
  - lib/table_structure/writer.rb
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module TableStructure
4
- module Schema
5
- module Column
6
- module Definition
7
- class Compiler
8
- DEFAULT_ATTRS = {
9
- name: nil,
10
- key: nil,
11
- value: nil,
12
- size: nil,
13
- omitted: false
14
- }.freeze
15
-
16
- DEFAULT_SIZE = 1
17
-
18
- def initialize(name, definitions, options)
19
- @name = name
20
- @definitions = definitions
21
- @options = options
22
- end
23
-
24
- def compile(context = nil)
25
- @definitions
26
- .map { |definition| Utils.evaluate_callable(definition, context) }
27
- .map.with_index do |definition, i|
28
- validator = Validator.new(@name, i)
29
-
30
- [definition]
31
- .flatten
32
- .map do |definition|
33
- if definition.is_a?(Hash)
34
- definition = DEFAULT_ATTRS.merge(definition)
35
- omitted = definition.delete(:omitted)
36
- next if Utils.evaluate_callable(omitted, context)
37
-
38
- definition = evaluate_attrs(definition, context)
39
- validator.validate(**definition)
40
- definition[:size] = determine_size(**definition)
41
- definition
42
- elsif Utils.schema_instance?(definition)
43
- definition
44
- elsif Utils.schema_class?(definition)
45
- definition.new(context: context)
46
- elsif definition.nil? && @options[:nil_definitions_ignored]
47
- next
48
- else
49
- raise Error.new('Invalid definition.', @name, i)
50
- end
51
- end
52
- end
53
- .flatten
54
- .compact
55
- end
56
-
57
- private
58
-
59
- def evaluate_attrs(definition, context)
60
- size = Utils.evaluate_callable(definition[:size], context)
61
- definition.merge(size: size)
62
- end
63
-
64
- def determine_size(name:, key:, size:, **)
65
- return size if size
66
-
67
- [calculate_size(name), calculate_size(key)].max
68
- end
69
-
70
- def calculate_size(val)
71
- if val.is_a?(Array)
72
- return val.empty? ? DEFAULT_SIZE : val.size
73
- end
74
-
75
- DEFAULT_SIZE
76
- end
77
- end
78
- end
79
- end
80
- end
81
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module TableStructure
4
- module Schema
5
- module Column
6
- module Factory
7
- def self.create(name, definitions, context, options)
8
- Definition::Compiler
9
- .new(name, definitions, options)
10
- .compile(context)
11
- .map do |definition|
12
- if definition.is_a?(Hash)
13
- Attrs.new(**definition)
14
- else
15
- Schema.new(definition)
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module TableStructure
4
- module Schema
5
- module DSL
6
- module ResultBuilder
7
- DEFAULT_OPTIONS = {
8
- enabled_result_types: %i[array hash]
9
- }.freeze
10
-
11
- def result_builder(name, callable, **options)
12
- options = DEFAULT_OPTIONS.merge(options)
13
- options[:enabled_result_types] = [options[:enabled_result_types]].flatten
14
- result_builders[name] = {
15
- callable: callable,
16
- options: options
17
- }
18
- nil
19
- end
20
-
21
- def result_builders
22
- @__result_builders__ ||= {}
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module TableStructure
4
- module Schema
5
- class ResultBuilders
6
- DEFAULT_BUILDERS = {
7
- _to_hash_: {
8
- callable: lambda { |values, keys, *|
9
- keys.map.with_index { |key, i| [key || i, values[i]] }.to_h
10
- },
11
- options: {
12
- enabled_result_types: [:hash]
13
- }
14
- }
15
- }.freeze
16
-
17
- def initialize(builders)
18
- @builders = builders
19
- end
20
-
21
- def extend_methods_for(table, result_type: :array)
22
- builders = select_builders(result_type)
23
-
24
- methods = {}
25
- unless builders.empty?
26
- table_context = table.instance_variable_get(:@context)
27
- table_keys = table.send(:keys)
28
-
29
- methods[:header] = create_method(builders, table_keys, table_context)
30
- methods[:row] = create_method(builders, table_keys, table_context)
31
- end
32
-
33
- return if methods.empty?
34
-
35
- table.extend ResultBuilder.new(methods)
36
- end
37
-
38
- private
39
-
40
- def select_builders(result_type)
41
- DEFAULT_BUILDERS
42
- .merge(@builders)
43
- .select { |_k, v| v[:options][:enabled_result_types].include?(result_type) }
44
- .map { |k, v| [k, v[:callable]] }
45
- .to_h
46
- end
47
-
48
- def create_method(builders, table_keys, table_context)
49
- proc do |context: nil|
50
- values = super(context: context)
51
- builders
52
- .reduce(values) do |vals, (_, builder)|
53
- builder.call(vals, table_keys, context, table_context)
54
- end
55
- end
56
- end
57
- end
58
-
59
- class ResultBuilder < Module
60
- def initialize(methods)
61
- methods.each do |name, method|
62
- define_method(name, &method)
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module TableStructure
4
- module Schema
5
- class Table
6
- class KeyDecorator
7
- def initialize(prefix: nil, suffix: nil)
8
- @prefix = prefix
9
- @suffix = suffix
10
- end
11
-
12
- def decorate(keys)
13
- return keys unless has_any_options?
14
-
15
- keys.map do |key|
16
- next key unless key
17
-
18
- decorated_key = "#{@prefix}#{key}#{@suffix}"
19
- decorated_key = decorated_key.to_sym if key.is_a?(Symbol)
20
- decorated_key
21
- end
22
- end
23
-
24
- private
25
-
26
- def has_any_options?
27
- @prefix || @suffix
28
- end
29
- end
30
- end
31
- end
32
- end