nxt_registry 0.3.0 → 0.3.1

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
  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: []