config_mapper 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8ef98e7511cb9930fbda99d63064fc49e7634c25
4
- data.tar.gz: b22f51b95e5248c20f91f353fddbd304b0a6ed26
3
+ metadata.gz: 2b50eb5ad224762a6891a4bb75077f7cf24dd19a
4
+ data.tar.gz: ee8a164e3478984a0793df79345af4bbaa67054a
5
5
  SHA512:
6
- metadata.gz: eafa293ee0625f4c8d330f00f59a2618affeff679d5189e24087734cd4601f45bf32c0f7fdfaf380e643c7a9a0762b34581a6efc2f918eae237fc918e35b02e8
7
- data.tar.gz: f59d8a5d5a27502ae8bb457aa083a14be7d2f35be5af3a2550d2347142ab452bfb76b25f17f343e6fd193ea267cdcadb8049853366ebba2b21699aa37c1b1cef
6
+ metadata.gz: 4f16a33006c27cc333e7bed302052b372728755a900103f42781f116639cde0a6af56c598d2335677bba75b031ed49e0c3c70162d00c5bcce0cce0085d80a302
7
+ data.tar.gz: 0ef76dfb3980e16c6e671e5a055e4deb546408c1515f7675da6bccf43d10357d4432b7c43262f8767f7b2017e42765e869ca44823c502480661098b5cde93b52
data/.rubocop.yml CHANGED
@@ -44,6 +44,9 @@ Style/FileName:
44
44
  Style/HashSyntax:
45
45
  EnforcedStyle: hash_rockets
46
46
 
47
+ Style/Lambda:
48
+ Enabled: false
49
+
47
50
  Style/StringLiterals:
48
51
  EnforcedStyle: double_quotes
49
52
 
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # ConfigMapper
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/config_mapper.png)](http://badge.fury.io/rb/config_mapper)
4
+ [![Build Status](https://secure.travis-ci.org/mdub/config_mapper.png?branch=master)](http://travis-ci.org/mdub/config_mapper)
5
+
3
6
  ConfigMapper maps configuration data onto Ruby objects.
4
7
 
5
8
  ## Usage
@@ -119,8 +122,8 @@ require "config_mapper/config_struct"
119
122
  class State < ConfigMapper::ConfigStruct
120
123
 
121
124
  component :position do
122
- attribute(:x) { |arg| Integer(arg) }
123
- attribute(:y) { |arg| Integer(arg) }
125
+ attribute :x
126
+ attribute :y
124
127
  end
125
128
 
126
129
  attribute :orientation
@@ -128,35 +131,48 @@ class State < ConfigMapper::ConfigStruct
128
131
  end
129
132
  ```
130
133
 
131
- By default, declared attributes are assumed to be mandatory. The
132
- `ConfigStruct#config_errors` method returns errors for each unset mandatory
133
- attribute.
134
+ `ConfigStruct#config_errors` returns errors for each unset mandatory attribute.
134
135
 
135
136
  ```ruby
136
137
  state = State.new
137
138
  state.position.x = 3
138
139
  state.position.y = 4
139
140
  state.config_errors
140
- #=> { ".orientation" => "no value provided" }
141
+ #=> { ".orientation" => #<ConfigMapper::ConfigStruct::NoValueProvided: no value provided> }
141
142
  ```
142
143
 
143
144
  `#config_errors` can be overridden to provide custom semantic validation.
144
145
 
145
- Attributes can be given default values. Provide an explicit `nil` default to
146
- mark an attribute as optional, e.g.
146
+ Attributes can be given default values. Specify a default value of `nil` to mark an attribute as optional, e.g.
147
147
 
148
148
  ```ruby
149
149
  class Address < ConfigMapper::ConfigStruct
150
-
151
150
  attribute :host
152
151
  attribute :port, :default => 80
153
152
  attribute :path, :default => nil
153
+ end
154
+ ```
155
+
156
+ If a block is provided when an `attribute` is declared, it is used to validate values when they are set, and/or coerce them to a canonical type. The block should raise `ArgumentError` to indicate an invalid value.
157
+
158
+ ```ruby
159
+ class Server < ConfigMapper::ConfigStruct
160
+
161
+ attribute :host do |arg|
162
+ unless arg =~ /^\w+(\.\w+)+$/
163
+ raise ArgumentError, "invalid hostname: #{arg}"
164
+ end
165
+ arg
166
+ end
167
+
168
+ attribute :port do |arg|
169
+ Integer(arg)
170
+ end
154
171
 
155
172
  end
156
173
  ```
157
174
 
158
- `ConfigStruct#configure_with` maps data into the object, and combines mapping errors and
159
- semantic errors (returned by `#config_errors`) into a single Hash:
175
+ `ConfigStruct#configure_with` maps data into the object, and combines mapping errors and semantic errors (returned by `#config_errors`) into a single Hash:
160
176
 
161
177
  ```ruby
162
178
  data = {
@@ -15,6 +15,14 @@ module ConfigMapper
15
15
  @entries[key] ||= @entry_type.call
16
16
  end
17
17
 
18
+ def to_h
19
+ {}.tap do |result|
20
+ @entries.each do |key, value|
21
+ result[key] = value.to_h
22
+ end
23
+ end
24
+ end
25
+
18
26
  extend Forwardable
19
27
 
20
28
  def_delegators :@entries, :each, :empty?, :keys, :map, :size
@@ -21,21 +21,24 @@ module ConfigMapper
21
21
  # @options options [String] :default (nil) default value
22
22
  # @yield type-coercion block
23
23
  #
24
- def attribute(name, options = {}, &coerce_block)
24
+ def attribute(name, options = {})
25
25
  name = name.to_sym
26
+ required = true
27
+ default_value = nil
26
28
  if options.key?(:default)
27
29
  default_value = options.fetch(:default).freeze
28
- attribute_initializers[name] = proc { default_value }
29
- else
30
- required_attributes << name
30
+ required = false if default_value.nil?
31
31
  end
32
+ attribute_initializers[name] = proc { default_value }
33
+ required_attributes << name if required
32
34
  attr_reader(name)
33
- if coerce_block
34
- define_method("#{name}=") do |arg|
35
- instance_variable_set("@#{name}", coerce_block.call(arg))
35
+ define_method("#{name}=") do |value|
36
+ if value.nil?
37
+ raise NoValueProvided if required
38
+ else
39
+ value = yield(value) if block_given?
36
40
  end
37
- else
38
- attr_writer(name)
41
+ instance_variable_set("@#{name}", value)
39
42
  end
40
43
  end
41
44
 
@@ -125,6 +128,22 @@ module ConfigMapper
125
128
  config_errors.merge(errors)
126
129
  end
127
130
 
131
+ # Return the configuration as a Hash.
132
+ #
133
+ # @return [Hash] serializable config data
134
+ #
135
+ def to_h
136
+ {}.tap do |result|
137
+ self.class.attribute_initializers.keys.each do |attr_name|
138
+ value = send(attr_name)
139
+ if value && value.respond_to?(:to_h) && !value.is_a?(Array)
140
+ value = value.to_h
141
+ end
142
+ result[attr_name.to_s] = value
143
+ end
144
+ end
145
+ end
146
+
128
147
  private
129
148
 
130
149
  def components
@@ -140,13 +159,19 @@ module ConfigMapper
140
159
  end
141
160
  end
142
161
 
143
- NOT_SET = "no value provided".freeze
162
+ class NoValueProvided < ArgumentError
163
+
164
+ def initialize
165
+ super("no value provided")
166
+ end
167
+
168
+ end
144
169
 
145
170
  def missing_required_attribute_errors
146
171
  {}.tap do |errors|
147
172
  self.class.required_attributes.each do |name|
148
- unless instance_variable_defined?("@#{name}")
149
- errors[".#{name}"] = NOT_SET
173
+ if instance_variable_get("@#{name}").nil?
174
+ errors[".#{name}"] = NoValueProvided.new
150
175
  end
151
176
  end
152
177
  end
@@ -1,5 +1,5 @@
1
1
  module ConfigMapper
2
2
 
3
- VERSION = "1.1.1"
3
+ VERSION = "1.2.0".freeze
4
4
 
5
5
  end
data/lib/config_mapper.rb CHANGED
@@ -25,7 +25,7 @@ module ConfigMapper
25
25
  mapper_for(target).configure_with(data)
26
26
  end
27
27
 
28
- alias_method :set, :configure_with
28
+ alias set configure_with
29
29
 
30
30
  def mapper_for(target)
31
31
  if target.is_a?(Hash) || target.is_a?(ConfigMapper::ConfigDict)
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.1.1
4
+ version: 1.2.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: 2016-02-29 00:00:00.000000000 Z
11
+ date: 2016-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -96,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
96
  version: '0'
97
97
  requirements: []
98
98
  rubyforge_project:
99
- rubygems_version: 2.5.2
99
+ rubygems_version: 2.5.1
100
100
  signing_key:
101
101
  specification_version: 4
102
102
  summary: Maps config data onto plain old objects