nxt_registry 0.3.0 → 0.3.1

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
  SHA256:
3
- metadata.gz: 84faa74573904a66ff0f574195ef5ab7e74508d097f04d1e7f43afcfe4867432
4
- data.tar.gz: 8f5c04f6eef2f3b7328567d2b1e49fe9e862d915b572e18fdefd32cb71c24fc2
3
+ metadata.gz: 121af631fa49f89d2b47599adcf3122401409299f65d755f7ba3cb418734cdf4
4
+ data.tar.gz: e6d94a93edf4bb250186242e5892f0dcda7df9c71c23be5a4b8ddca5420eed0d
5
5
  SHA512:
6
- metadata.gz: 293d5d1d418152c704ea04aaff4dd392b901c40a9460f1858e5cf6581a0c6fe58041bbe163b8aff3fbcdd9848638f7715e87046b14666f5111677c5241d67eea
7
- data.tar.gz: 0475b0d48a589d90ff548d2c7f414bab38e5360fb46cafee35a29e83203a72fcd8fbce4870fbd7862b182ac38558f48567417808c5d400f4a728ff7dbf353a53
6
+ metadata.gz: b0601a25a8325fe3fb21f2cfdf25e8710c3b219c135999fea2bc0bc325713bf3f20f321f4aadbdffcc50f4d03557c0fc4ba1008d52efe69e3f38400e4dfdf0b9
7
+ data.tar.gz: 770c75ffca22aa1c7de4af1de955abf2044d9dca121b566e277f5d0fd637e41bc58231ae1edfd38a11af69279c05928f001e98561edae77edd060499bcf9bdf4
@@ -1,3 +1,7 @@
1
+ # v0.3.1 2020-09-23
2
+
3
+ - Allow to define custom accessors for registries
4
+
1
5
  # v0.3.0 2020-09-10
2
6
 
3
7
  ### Breaking Changes
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nxt_registry (0.3.0)
4
+ nxt_registry (0.3.1)
5
5
  activesupport
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -59,7 +59,7 @@ registry.resolve(:aki) # => 'Aki'
59
59
 
60
60
  ## Class Level
61
61
 
62
- You can register registries on the class level simply by extending your class with `NxtRegistry`
62
+ You can add registries on the class level simply by extending your class with `NxtRegistry`
63
63
 
64
64
  ```ruby
65
65
  class OtherExample
@@ -130,17 +130,41 @@ class Layer
130
130
  end
131
131
  end
132
132
 
133
+ # On every upper level every resolve returns a registry
133
134
  Layer.registry(:from) # => Registry[from]
134
-
135
135
  Layer.registry(:from).resolve(:munich) # => Registry[to] -> {}
136
136
  Layer.registry(:from).resolve(:amsterdam) # => Registry[to] -> {}
137
137
  Layer.registry(:from).resolve(:any_key) # => Registry[to] -> {}
138
-
139
138
  Layer.registry(:from).resolve(:munich, :amsterdam) # => Registry[via] -> {}
139
+
140
+ # Register a value on the bottom level
140
141
  Layer.registry(:from).resolve(:munich, :amsterdam).register(:train, -> { 'train' })
142
+ # Resolve the complete path
141
143
  Layer.registry(:from).resolve(:munich, :amsterdam, :train) # => 'train'
142
144
  ```
143
145
 
146
+ For registries with multiple levels the normal syntax for registering and resolving becomes quite weird and unreadable. This is why
147
+ every registry can be accessed through it's name or a custom accessor. The above example then can be simplified as follows.
148
+
149
+ ```ruby
150
+ class Layer
151
+ extend NxtRegistry
152
+
153
+ registry :path, accessor: :from do # registry named path, can be accessed with .from(...)
154
+ level :to do
155
+ level :via
156
+ end
157
+ end
158
+ end
159
+
160
+ # Register a value
161
+ Layer.registry(:path).from(:munich).to(:amsterdam).via(:train, -> { 'train' })
162
+ # Resolve the complete path
163
+ Layer.registry(:path).from(:munich).to(:amsterdam).via(:train) # => 'train'
164
+ ```
165
+
166
+ *Note that this feature is also available for registries with a single level only.*
167
+
144
168
  ### Restrict attributes to a certain set
145
169
 
146
170
  Use `attrs` to restrict which attributes can be registered on a specific level.
@@ -1,31 +1,42 @@
1
1
  require 'active_support/core_ext'
2
- require "nxt_registry/version"
3
- require "nxt_registry/blank"
4
- require "nxt_registry/attribute"
5
- require "nxt_registry/errors"
6
- require "nxt_registry/registry_builder"
7
- require "nxt_registry/registry"
8
- require "nxt_registry/recursive_registry"
2
+ require 'nxt_registry/version'
3
+ require 'nxt_registry/blank'
4
+ require 'nxt_registry/attribute'
5
+ require 'nxt_registry/errors'
6
+ require 'nxt_registry/registry_builder'
7
+ require 'nxt_registry/registry'
8
+ require 'nxt_registry/recursive_registry'
9
9
 
10
10
  module NxtRegistry
11
11
  def registry(name, **options, &config)
12
- return registries.fetch(name) if registries.key?(name)
13
-
14
- registry = Registry.new(name, **options, &config)
15
- registries[name] ||= registry
16
- registry
12
+ build_registry(Registry, name, **options, &config)
17
13
  end
18
14
 
19
15
  def recursive_registry(name, **options, &config)
20
- return registries.fetch(name) if registries.key?(name)
21
-
22
- registry = RecursiveRegistry.new(name, **options, &config)
23
- registries[name] ||= registry
24
- registry
16
+ build_registry(RecursiveRegistry, name, **options, &config)
25
17
  end
26
18
 
27
19
  private
28
20
 
21
+ def build_registry(registry_class, name, **options, &config)
22
+ if registries.key?(name)
23
+ registry = registries.fetch(name)
24
+ if registry.configured
25
+ registry
26
+ else
27
+ raise_unconfigured_registry_accessed(name)
28
+ end
29
+ else
30
+ registry = registry_class.new(name, **options, &config)
31
+ registries[name] ||= registry
32
+ registry
33
+ end
34
+ end
35
+
36
+ def raise_unconfigured_registry_accessed(name)
37
+ raise ArgumentError, "The registry #{name} must be configured before accessed!"
38
+ end
39
+
29
40
  def registries
30
41
  @registries ||= {}
31
42
  end
@@ -1,25 +1,27 @@
1
1
  module NxtRegistry
2
2
  class Registry
3
3
  def initialize(name = object_id.to_s, **options, &config)
4
+ @options = options
4
5
  @name = name
5
6
  @parent = options[:parent]
6
7
  @is_leaf = true
7
8
  @namespace = build_namespace
8
9
  @config = config
9
- @options = options
10
10
  @store = {}
11
11
  @attrs = nil
12
+ @configured = false
12
13
 
13
14
  setup_defaults(options)
14
- configure(&config)
15
+ configure(&config) if block_given? || parent
15
16
  end
16
17
 
17
18
  attr_reader :name
19
+ attr_accessor :configured
18
20
 
19
21
  def level(name, **options, &config)
20
22
  options = options.merge(parent: self)
21
23
 
22
- if default.is_a?(Blank)
24
+ if is_a_blank?(default)
23
25
  self.is_leaf = false
24
26
 
25
27
  self.default = RegistryBuilder.new do
@@ -36,13 +38,13 @@ module NxtRegistry
36
38
  end
37
39
 
38
40
  def registry(name, **options, &config)
39
- options = options.merge(parent: self)
40
- register(name, Registry.new(name, **options, &config))
41
+ opts = options.merge(parent: self)
42
+ register(name, Registry.new(name, **opts, &config))
41
43
  end
42
44
 
43
45
  def registry!(name, **options, &config)
44
- options = options.merge(parent: self)
45
- register!(name, Registry.new(name, **options, &config))
46
+ opts = options.merge(parent: self)
47
+ register!(name, Registry.new(name, **opts, &config))
46
48
  end
47
49
 
48
50
  def attr(name)
@@ -61,37 +63,37 @@ module NxtRegistry
61
63
 
62
64
  def register(key = Blank.new, value = Blank.new, **options, &block)
63
65
  if block_given?
64
- if value.is_a?(Blank)
66
+ if is_a_blank?(value)
65
67
  registry(key, **options, &block)
66
68
  else
67
69
  raise_register_argument_error
68
70
  end
69
71
  else
70
- __register(key, value, raise: true)
72
+ __register(key, value, raise_on_key_already_registered: true)
71
73
  end
72
74
  end
73
75
 
74
76
  def register!(key = Blank.new, value = Blank.new, **options, &block)
75
77
  if block_given?
76
- if value.is_a?(Blank)
78
+ if is_a_blank?(value)
77
79
  registry!(key, **options, &block)
78
80
  else
79
81
  raise_register_argument_error
80
82
  end
81
83
  else
82
- __register(key, value, raise: false)
84
+ __register(key, value, raise_on_key_already_registered: false)
83
85
  end
84
86
  end
85
87
 
86
88
  def resolve!(*keys)
87
89
  keys.inject(self) do |current_registry, key|
88
- current_registry.send(:__resolve, key, raise: true)
90
+ current_registry.send(:__resolve, key, raise_on_key_not_registered: true)
89
91
  end
90
92
  end
91
93
 
92
94
  def resolve(*keys)
93
95
  keys.inject(self) do |current_registry, key|
94
- current_registry.send(:__resolve, key, raise: false) || break
96
+ current_registry.send(:__resolve, key, raise_on_key_not_registered: false) || break
95
97
  end
96
98
  end
97
99
 
@@ -141,6 +143,8 @@ module NxtRegistry
141
143
  instance_exec(&block)
142
144
  end
143
145
  end
146
+
147
+ self.configured = true
144
148
  end
145
149
 
146
150
  def to_s
@@ -151,33 +155,33 @@ module NxtRegistry
151
155
 
152
156
  private
153
157
 
154
- attr_reader :namespace, :parent, :config, :store, :options
158
+ attr_reader :namespace, :parent, :config, :store, :options, :accessor
155
159
  attr_accessor :is_leaf
156
160
 
157
161
  def is_leaf?
158
162
  @is_leaf
159
163
  end
160
164
 
161
- def __register(key, value, raise: true)
165
+ def __register(key, value, raise_on_key_already_registered: true)
162
166
  key = transformed_key(key)
163
167
 
164
168
  raise ArgumentError, "Not allowed to register values in a registry that contains nested registries" unless is_leaf
165
169
  raise KeyError, "Keys are restricted to #{attrs.keys}" if attribute_not_allowed?(key)
166
170
 
167
- on_key_already_registered && on_key_already_registered.call(key) if store[key] && raise
171
+ on_key_already_registered && on_key_already_registered.call(key) if store[key] && raise_on_key_already_registered
168
172
 
169
173
  store[key] = value
170
174
  end
171
175
 
172
- def __resolve(key, raise: true)
176
+ def __resolve(key, raise_on_key_not_registered: true)
173
177
  key = transformed_key(key)
174
178
 
175
179
  value = if is_leaf?
176
180
  if store.key?(key)
177
181
  store.fetch(key)
178
182
  else
179
- if default.is_a?(Blank)
180
- return unless raise
183
+ if is_a_blank?(default)
184
+ return unless raise_on_key_not_registered
181
185
 
182
186
  on_key_not_registered && on_key_not_registered.call(key)
183
187
  else
@@ -205,24 +209,28 @@ module NxtRegistry
205
209
  end
206
210
 
207
211
  def define_interface
208
- define_singleton_method name do |key = Blank.new, value = Blank.new|
209
- return self if key.is_a?(Blank)
212
+ raise_invalid_accessor_name(accessor) if respond_to?(accessor)
213
+ accessor_with_bang = "#{accessor}!"
214
+ raise_invalid_accessor_name(accessor_with_bang) if respond_to?(accessor_with_bang)
215
+
216
+ define_singleton_method accessor do |key = Blank.new, value = Blank.new|
217
+ return self if is_a_blank?(key)
210
218
 
211
219
  key = transformed_key(key)
212
220
 
213
- if value.is_a?(Blank)
221
+ if is_a_blank?(value)
214
222
  resolve(key)
215
223
  else
216
224
  register(key, value)
217
225
  end
218
226
  end
219
227
 
220
- define_singleton_method "#{name}!" do |key = Blank.new, value = Blank.new|
221
- return self if key.is_a?(Blank)
228
+ define_singleton_method accessor_with_bang do |key = Blank.new, value = Blank.new|
229
+ return self if is_a_blank?(key)
222
230
 
223
231
  key = transformed_key(key)
224
232
 
225
- if value.is_a?(Blank)
233
+ if is_a_blank?(value)
226
234
  resolve!(key)
227
235
  else
228
236
  register!(key, value)
@@ -236,6 +244,7 @@ module NxtRegistry
236
244
  @call = options.fetch(:call) { true }
237
245
  @resolver = options.fetch(:resolver, false)
238
246
  @transform_keys = options.fetch(:transform_keys) { ->(key) { key.to_s } }
247
+ @accessor = options.fetch(:accessor) { name }
239
248
 
240
249
  @on_key_already_registered = options.fetch(:on_key_already_registered) { ->(key) { raise_key_already_registered_error(key) } }
241
250
  @on_key_not_registered = options.fetch(:on_key_not_registered) { ->(key) { raise_key_not_registered_error(key) } }
@@ -246,7 +255,7 @@ module NxtRegistry
246
255
  define_singleton_method attribute do |value = Blank.new, &block|
247
256
  value = block if block
248
257
 
249
- if value.is_a?(Blank)
258
+ if is_a_blank?(value)
250
259
  instance_variable_get("@#{attribute}")
251
260
  else
252
261
  instance_variable_set("@#{attribute}", value)
@@ -284,7 +293,7 @@ module NxtRegistry
284
293
  def transformed_key(key)
285
294
  @transformed_key ||= {}
286
295
  @transformed_key[key] ||= begin
287
- if transform_keys && !key.is_a?(Blank)
296
+ if transform_keys && !is_a_blank?(key)
288
297
  transform_keys.call(key)
289
298
  else
290
299
  key
@@ -305,5 +314,13 @@ module NxtRegistry
305
314
  def raise_register_argument_error
306
315
  raise ArgumentError, 'Either provide a key value pair or a block to register'
307
316
  end
317
+
318
+ def is_a_blank?(value)
319
+ value.is_a?(Blank)
320
+ end
321
+
322
+ def raise_invalid_accessor_name(name)
323
+ raise ArgumentError, "#{self} already implements a method named: #{name}. Please choose a different accessor name"
324
+ end
308
325
  end
309
326
  end
@@ -1,3 +1,3 @@
1
1
  module NxtRegistry
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.name = "nxt_registry"
7
7
  spec.version = NxtRegistry::VERSION
8
8
  spec.authors = ["Andreas Robecke", "Nils Sommer", "Raphael Kallensee", "Lütfi Demirci"]
9
- spec.email = ["a.robecke@getsafe.de"]
9
+ spec.email = ['a.robecke@hellogetsafe.com', 'andreas@robecke.de']
10
10
 
11
11
  spec.summary = %q{nxt_registry is a simple implementation of the container pattern}
12
12
  spec.homepage = "https://github.com/nxt-insurance"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nxt_registry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Robecke
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2020-09-17 00:00:00.000000000 Z
14
+ date: 2020-09-25 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
@@ -85,7 +85,8 @@ dependencies:
85
85
  version: '0'
86
86
  description:
87
87
  email:
88
- - a.robecke@getsafe.de
88
+ - a.robecke@hellogetsafe.com
89
+ - andreas@robecke.de
89
90
  executables: []
90
91
  extensions: []
91
92
  extra_rdoc_files: []