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