config_mapper 1.6.0 → 1.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cad2a71b7850554a0a981b18d91bb1198cd16f8a
4
- data.tar.gz: 305d415a5243d35b97d4a9b881fe51fad55217c5
3
+ metadata.gz: c439738a98e1865c82d286061ea400b181ff9899
4
+ data.tar.gz: 9a850ec8e62445f822838cb388dee7b1f3fae69f
5
5
  SHA512:
6
- metadata.gz: 91509bfa9e31c03bb8093c434942980cbd8616fffb22b7d0b4bf21f64edd01b750b7e9dd270c2d491452ae191455dcdf9c49724feb1d9f5076c3421c54d16c6d
7
- data.tar.gz: 423dcae0bc0c14b13979fbf1a10980b43c5e669a23fa521ad8b864fba965f83f3e5ee5bab1c569a8b6c2c47de017570964bd08ae7ef3b0cd36f37cb20c3da6b1
6
+ metadata.gz: cfe874d019e5d3f0195b42a0945d6d5f335c660e6a45bfc6b93f7a32b1af1bb193aa5088c3f2ae0dcb543b49fca33394813158bd167b90988643af7cd5d9d128
7
+ data.tar.gz: 10de84239f89b4bd1a83a62ed172537684a28add36cf5e52e87c76b109f9ae6267f52d9ee030d8612c402f662b8c70e07028f5592147589ac64612d627d5280f
data/README.md CHANGED
@@ -217,6 +217,30 @@ class State < ConfigMapper::ConfigStruct
217
217
  end
218
218
  ```
219
219
 
220
+ `component_list` declares a nested list of configurable objects, indexed by position, and `component_dict` declares a dictionary (map) of configurable objects, indexed by an arbitrary key.
221
+
222
+ ```ruby
223
+ class Polygon < ConfigMapper::ConfigStruct
224
+
225
+ component_list :points do
226
+ attribute :x
227
+ attribute :y
228
+ end
229
+
230
+ end
231
+
232
+ class Cargo < ConfigMapper::ConfigStruct
233
+
234
+ component_dict :packages do
235
+ attribute :contents
236
+ attribute :weight, Float
237
+ end
238
+
239
+ end
240
+ ```
241
+
242
+ In both cases, new collection entries pop into existance the first time they are accessed.
243
+
220
244
  ### Semantic errors
221
245
 
222
246
  `ConfigStruct#config_errors` returns errors for each unset mandatory attribute.
@@ -1,5 +1,6 @@
1
1
  require "config_mapper/collection_mapper"
2
2
  require "config_mapper/config_dict"
3
+ require "config_mapper/config_list"
3
4
  require "config_mapper/object_mapper"
4
5
 
5
6
  # Supports marshalling of plain-old data (e.g. loaded from
@@ -0,0 +1,72 @@
1
+ require 'config_mapper'
2
+ require 'config_mapper/config_struct'
3
+ require "config_mapper/factory"
4
+ require "config_mapper/validator"
5
+ require "forwardable"
6
+
7
+ module ConfigMapper
8
+ class ConfigList
9
+
10
+ class Factory
11
+
12
+ def initialize(entry_factory)
13
+ @entry_factory = ConfigMapper::Factory.resolve(entry_factory)
14
+ end
15
+
16
+ attr_reader :entry_factory
17
+
18
+ def new
19
+ ConfigList.new(@entry_factory)
20
+ end
21
+
22
+ def config_doc
23
+ return {} unless entry_factory.respond_to?(:config_doc)
24
+ {}.tap do |result|
25
+ entry_factory.config_doc.each do |path, doc|
26
+ result["[N]#{path}"] = doc
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ def initialize(entry_factory)
34
+ @entry_factory = entry_factory
35
+ @entries = []
36
+ end
37
+
38
+ def [](index)
39
+ @entries[index] ||= @entry_factory.new
40
+ end
41
+
42
+ def to_a
43
+ map do |element|
44
+ case
45
+ when element.respond_to?(:to_h); element.to_h
46
+ when element.respond_to?(:to_a); element.to_a
47
+ else element
48
+ end
49
+ end
50
+ end
51
+
52
+ def config_errors
53
+ {}.tap do |errors|
54
+ each_with_index do |element, index|
55
+ next unless element.respond_to?(:config_errors)
56
+ prefix = "[#{index}]"
57
+ element.config_errors.each do |path, path_errors|
58
+ errors["#{prefix}#{path}"] = path_errors
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ extend Forwardable
65
+
66
+ def_delegators :@entries, :each, :each_with_index, :empty?, :map, :size
67
+
68
+ include Enumerable
69
+
70
+ end
71
+ end
72
+
@@ -89,6 +89,19 @@ module ConfigMapper
89
89
  component(name, type: ConfigDict::Factory.new(type, key_type), description: description)
90
90
  end
91
91
 
92
+ # Defines an array of sub-components.
93
+ #
94
+ # If a block is be provided, it will be `class_eval`ed to define the
95
+ # sub-components class.
96
+ #
97
+ # @param name [Symbol] list attribute name
98
+ # @param type [Class] base-class for component values
99
+ #
100
+ def component_list(name, type: ConfigStruct, description: nil, &block)
101
+ type = Class.new(type, &block) if block
102
+ component(name, type: ConfigList::Factory.new(type), description: description)
103
+ end
104
+
92
105
  # Generate documentation, as Ruby data.
93
106
  #
94
107
  # Returns an entry for each configurable path, detailing
@@ -159,6 +172,8 @@ module ConfigMapper
159
172
  value = send(attribute.name)
160
173
  if value && value.respond_to?(:to_h) && !value.is_a?(Array)
161
174
  value = value.to_h
175
+ elsif value && value.respond_to?(:to_a)
176
+ value = value.to_a
162
177
  end
163
178
  result[attribute.name.to_s] = value
164
179
  end
@@ -1,5 +1,5 @@
1
1
  module ConfigMapper
2
2
 
3
- VERSION = "1.6.0".freeze
3
+ VERSION = "1.7.0".freeze
4
4
 
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: config_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-13 00:00:00.000000000 Z
11
+ date: 2018-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -64,6 +64,7 @@ files:
64
64
  - lib/config_mapper.rb
65
65
  - lib/config_mapper/collection_mapper.rb
66
66
  - lib/config_mapper/config_dict.rb
67
+ - lib/config_mapper/config_list.rb
67
68
  - lib/config_mapper/config_struct.rb
68
69
  - lib/config_mapper/factory.rb
69
70
  - lib/config_mapper/mapper.rb