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 +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +27 -3
- data/lib/nxt_registry.rb +28 -17
- data/lib/nxt_registry/registry.rb +44 -27
- data/lib/nxt_registry/version.rb +1 -1
- data/nxt_registry.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 121af631fa49f89d2b47599adcf3122401409299f65d755f7ba3cb418734cdf4
|
4
|
+
data.tar.gz: e6d94a93edf4bb250186242e5892f0dcda7df9c71c23be5a4b8ddca5420eed0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0601a25a8325fe3fb21f2cfdf25e8710c3b219c135999fea2bc0bc325713bf3f20f321f4aadbdffcc50f4d03557c0fc4ba1008d52efe69e3f38400e4dfdf0b9
|
7
|
+
data.tar.gz: 770c75ffca22aa1c7de4af1de955abf2044d9dca121b566e277f5d0fd637e41bc58231ae1edfd38a11af69279c05928f001e98561edae77edd060499bcf9bdf4
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -59,7 +59,7 @@ registry.resolve(:aki) # => 'Aki'
|
|
59
59
|
|
60
60
|
## Class Level
|
61
61
|
|
62
|
-
You can
|
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.
|
data/lib/nxt_registry.rb
CHANGED
@@ -1,31 +1,42 @@
|
|
1
1
|
require 'active_support/core_ext'
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
40
|
-
register(name, Registry.new(name, **
|
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
|
-
|
45
|
-
register!(name, Registry.new(name, **
|
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
|
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,
|
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
|
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,
|
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,
|
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,
|
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,
|
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] &&
|
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,
|
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
|
180
|
-
return unless
|
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
|
-
|
209
|
-
|
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
|
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
|
221
|
-
return self if
|
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
|
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
|
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 && !
|
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
|
data/lib/nxt_registry/version.rb
CHANGED
data/nxt_registry.gemspec
CHANGED
@@ -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 = [
|
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.
|
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-
|
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@
|
88
|
+
- a.robecke@hellogetsafe.com
|
89
|
+
- andreas@robecke.de
|
89
90
|
executables: []
|
90
91
|
extensions: []
|
91
92
|
extra_rdoc_files: []
|