smart_initializer 0.1.0.alpha4 → 0.3.2
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/.rubocop.yml +1 -1
- data/.travis.yml +36 -5
- data/CHANGELOG.md +23 -0
- data/Gemfile.lock +63 -43
- data/README.md +184 -26
- data/Rakefile +1 -1
- data/bin/rspec +54 -0
- data/gemfiles/with_external_deps.gemfile +7 -0
- data/gemfiles/with_external_deps.gemfile.lock +102 -0
- data/gemfiles/without_external_deps.gemfile +5 -0
- data/gemfiles/without_external_deps.gemfile.lock +100 -0
- data/lib/smart_core/initializer.rb +41 -35
- data/lib/smart_core/initializer/attribute.rb +12 -4
- data/lib/smart_core/initializer/attribute/factory.rb +47 -27
- data/lib/smart_core/initializer/attribute/parameters.rb +12 -4
- data/lib/smart_core/initializer/configuration.rb +33 -0
- data/lib/smart_core/initializer/constructor.rb +21 -8
- data/lib/smart_core/initializer/constructor/definer.rb +34 -11
- data/lib/smart_core/initializer/dsl.rb +27 -7
- data/lib/smart_core/initializer/errors.rb +44 -0
- data/lib/smart_core/initializer/functionality.rb +37 -0
- data/lib/smart_core/initializer/instance_attribute_accessing.rb +51 -0
- data/lib/smart_core/initializer/plugins.rb +17 -0
- data/lib/smart_core/initializer/plugins/abstract.rb +55 -0
- data/lib/smart_core/initializer/plugins/access_mixin.rb +47 -0
- data/lib/smart_core/initializer/plugins/registry.rb +166 -0
- data/lib/smart_core/initializer/plugins/registry_interface.rb +77 -0
- data/lib/smart_core/initializer/plugins/thy_types.rb +30 -0
- data/lib/smart_core/initializer/plugins/thy_types/errors.rb +11 -0
- data/lib/smart_core/initializer/plugins/thy_types/thy_types.rb +23 -0
- data/lib/smart_core/initializer/plugins/thy_types/thy_types/abstract_factory.rb +78 -0
- data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation.rb +12 -0
- data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/base.rb +9 -0
- data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/cast.rb +21 -0
- data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/valid.rb +16 -0
- data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/validate.rb +19 -0
- data/lib/smart_core/initializer/settings.rb +49 -0
- data/lib/smart_core/initializer/settings/duplicator.rb +20 -0
- data/lib/smart_core/initializer/settings/type_system.rb +69 -0
- data/lib/smart_core/initializer/type_system.rb +16 -0
- data/lib/smart_core/initializer/type_system/interop.rb +103 -0
- data/lib/smart_core/initializer/type_system/interop/abstract_factory.rb +70 -0
- data/lib/smart_core/initializer/type_system/interop/aliasing.rb +72 -0
- data/lib/smart_core/initializer/type_system/interop/aliasing/alias_list.rb +141 -0
- data/lib/smart_core/initializer/type_system/interop/operation.rb +30 -0
- data/lib/smart_core/initializer/type_system/registry.rb +174 -0
- data/lib/smart_core/initializer/type_system/registry_interface.rb +102 -0
- data/lib/smart_core/initializer/type_system/smart_types.rb +48 -0
- data/lib/smart_core/initializer/type_system/smart_types/abstract_factory.rb +72 -0
- data/lib/smart_core/initializer/type_system/smart_types/operation.rb +13 -0
- data/lib/smart_core/initializer/type_system/smart_types/operation/base.rb +8 -0
- data/lib/smart_core/initializer/type_system/smart_types/operation/cast.rb +16 -0
- data/lib/smart_core/initializer/type_system/smart_types/operation/valid.rb +16 -0
- data/lib/smart_core/initializer/type_system/smart_types/operation/validate.rb +16 -0
- data/lib/smart_core/initializer/version.rb +2 -1
- data/smart_initializer.gemspec +13 -9
- metadata +68 -17
- data/lib/smart_core/initializer/attribute/init_extension.rb +0 -4
- data/lib/smart_core/initializer/type_aliasing.rb +0 -50
- data/lib/smart_core/initializer/type_aliasing/alias_list.rb +0 -101
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.3.0
|
5
|
+
module SmartCore::Initializer::InstanceAttributeAccessing
|
6
|
+
# @return [Hash<Symbol,Any>]
|
7
|
+
#
|
8
|
+
# @api public
|
9
|
+
# @since 0.3.0
|
10
|
+
def __params__
|
11
|
+
__collect_params__
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Hash<Symbol,Any>]
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
# @since 0.3.0
|
18
|
+
def __options__
|
19
|
+
__collect_options__
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Hash<Symbol,Any>]
|
23
|
+
#
|
24
|
+
# @api public
|
25
|
+
# @since 0.3.0
|
26
|
+
def __attributes__
|
27
|
+
__collect_params__.merge(__collect_options__)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# @return [Hash<Symbol,Any>]
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
# @since 0.3.0
|
36
|
+
def __collect_params__
|
37
|
+
self.class.__params__.each_with_object({}) do |param, memo|
|
38
|
+
memo[param.name] = instance_variable_get("@#{param.name}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Hash<Symbol,Any>]
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
# @since 0.3.0
|
46
|
+
def __collect_options__
|
47
|
+
self.class.__options__.each_with_object({}) do |option, memo|
|
48
|
+
memo[option.name] = instance_variable_get("@#{option.name}")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
module SmartCore::Initializer::Plugins
|
6
|
+
require_relative 'plugins/abstract'
|
7
|
+
require_relative 'plugins/registry'
|
8
|
+
require_relative 'plugins/registry_interface.rb'
|
9
|
+
require_relative 'plugins/access_mixin'
|
10
|
+
require_relative 'plugins/thy_types'
|
11
|
+
|
12
|
+
# @since 0.1.0
|
13
|
+
extend SmartCore::Initializer::Plugins::RegistryInterface
|
14
|
+
|
15
|
+
# @since 0.1.0
|
16
|
+
register_plugin('thy_types', SmartCore::Initializer::Plugins::ThyTypes)
|
17
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Initializer::Plugins::Abstract
|
6
|
+
class << self
|
7
|
+
# @param child_klass [Class]
|
8
|
+
# @return [void]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
def inherited(child_klass)
|
13
|
+
child_klass.instance_variable_set(:@__loaded__, false)
|
14
|
+
child_klass.instance_variable_set(:@__lock__, Mutex.new)
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [void]
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
# @since 0.1.0
|
22
|
+
def load!
|
23
|
+
__thread_safe__ do
|
24
|
+
unless @__loaded__
|
25
|
+
@__loaded__ = true
|
26
|
+
install!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Boolean]
|
32
|
+
#
|
33
|
+
# @api private
|
34
|
+
# @since 0.1.0
|
35
|
+
def loaded?
|
36
|
+
__thread_safe__ { @__loaded__ }
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# @return [void]
|
42
|
+
#
|
43
|
+
# @api private
|
44
|
+
# @since 0.1.0
|
45
|
+
def install!; end
|
46
|
+
|
47
|
+
# @return [Any]
|
48
|
+
#
|
49
|
+
# @api private
|
50
|
+
# @since 0.1.0
|
51
|
+
def __thread_safe__
|
52
|
+
@__lock__.synchronize { yield }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
module SmartCore::Initializer::Plugins::AccessMixin
|
6
|
+
# @param plugin_name [Symbol, String]
|
7
|
+
# @return [void]
|
8
|
+
#
|
9
|
+
# @see SmartCore::Initializer::Plugins
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
# @since 0.1.0
|
13
|
+
def plugin(plugin_name)
|
14
|
+
SmartCore::Initializer::Plugins.load(plugin_name)
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Array<String>]
|
18
|
+
#
|
19
|
+
# @see SmartCore::Initializer::Plugins
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
# @since 0.1.0
|
23
|
+
def plugins
|
24
|
+
SmartCore::Initializer::Plugins.names
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Hash<String,Class<SmartCore::Initializer::Plugins::Abstract>>]
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
# @since 0.1.0
|
31
|
+
def loaded_plugins
|
32
|
+
SmartCore::Initializer::Plugins.loaded_plugins
|
33
|
+
end
|
34
|
+
alias_method :enabled_plugins, :loaded_plugins
|
35
|
+
|
36
|
+
# @param plugin_name [String, Symbol]
|
37
|
+
# @param plugin_klass [Class<SmartCore::Initializer::Plugins::Abstract>]
|
38
|
+
# @return [void]
|
39
|
+
#
|
40
|
+
# @see SmartCore::Initializer::Plugins
|
41
|
+
#
|
42
|
+
# @api public
|
43
|
+
# @since 0.1.0
|
44
|
+
def register_plugin(plugin_name, plugin_klass)
|
45
|
+
SmartCore::Initializer::Plugins.register_plugin(plugin_name, plugin_klass)
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Initializer::Plugins::Registry
|
6
|
+
# @since 0.1.0
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
# @return [void]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
# @since 0.1.0
|
13
|
+
def initialize
|
14
|
+
@plugin_set = {}
|
15
|
+
@access_lock = Mutex.new
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param plugin_name [Symbol, String]
|
19
|
+
# @return [SmartCore::Initializer::Plugins::Abstract]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
# @since 0.1.0
|
23
|
+
def [](plugin_name)
|
24
|
+
thread_safe { fetch(plugin_name) }
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param plugin_name [Symbol, String]
|
28
|
+
# @param plugin_module [SmartCore::Initializer::Plugins::Abstract]
|
29
|
+
# @return [void]
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
# @since 0.1.0
|
33
|
+
def register(plugin_name, plugin_module)
|
34
|
+
thread_safe { apply(plugin_name, plugin_module) }
|
35
|
+
end
|
36
|
+
alias_method :[]=, :register
|
37
|
+
|
38
|
+
# @return [Array<String>]
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
# @since 0.1.0
|
42
|
+
def names
|
43
|
+
thread_safe { plugin_names }
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Hash<String,Class<SmartCore::Initializer::Plugins::Abstract>>]
|
47
|
+
#
|
48
|
+
# @api private
|
49
|
+
# @since 0.1.0
|
50
|
+
def loaded
|
51
|
+
thread_safe { loaded_plugins }
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param block [Block]
|
55
|
+
# @return [Enumerable]
|
56
|
+
#
|
57
|
+
# @api private
|
58
|
+
# @since 0.1.0
|
59
|
+
def each(&block)
|
60
|
+
thread_safe { iterate(&block) }
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
# @return [Hash]
|
66
|
+
#
|
67
|
+
# @api private
|
68
|
+
# @since 0.1.0
|
69
|
+
attr_reader :plugin_set
|
70
|
+
|
71
|
+
# @return [Mutex]
|
72
|
+
#
|
73
|
+
# @api private
|
74
|
+
# @since 0.1.0
|
75
|
+
attr_reader :access_lock
|
76
|
+
|
77
|
+
# @return [void]
|
78
|
+
#
|
79
|
+
# @api private
|
80
|
+
# @since 0.1.0
|
81
|
+
def thread_safe
|
82
|
+
access_lock.synchronize { yield if block_given? }
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [Array<String>]
|
86
|
+
#
|
87
|
+
# @api private
|
88
|
+
# @since 0.1.0
|
89
|
+
def plugin_names
|
90
|
+
plugin_set.keys
|
91
|
+
end
|
92
|
+
|
93
|
+
# @param block [Block]
|
94
|
+
# @return [Enumerable]
|
95
|
+
#
|
96
|
+
# @api private
|
97
|
+
# @since 0.1.0
|
98
|
+
def iterate(&block)
|
99
|
+
block_given? ? plugin_set.each_pair(&block) : plugin_set.each_pair
|
100
|
+
end
|
101
|
+
|
102
|
+
# @param plugin_name [String]
|
103
|
+
# @return [Boolean]
|
104
|
+
#
|
105
|
+
# @api private
|
106
|
+
# @since 0.1.0
|
107
|
+
def registered?(plugin_name)
|
108
|
+
plugin_set.key?(plugin_name)
|
109
|
+
end
|
110
|
+
|
111
|
+
# @return [Array<SmartCore::Initializer::Plugins::Abstract>]
|
112
|
+
#
|
113
|
+
# @api private
|
114
|
+
# @since 0.1.0
|
115
|
+
def loaded_plugins
|
116
|
+
plugin_set.select { |_plugin_name, plugin_module| plugin_module.loaded? }
|
117
|
+
end
|
118
|
+
|
119
|
+
# @param plugin_name [Symbol, String]
|
120
|
+
# @param plugin_module [SmartCore::Initializer::Plugins::Abstract]
|
121
|
+
# @return [void]
|
122
|
+
#
|
123
|
+
# @raise [SmartCore::Initializer::AlreadyRegisteredPluginError]
|
124
|
+
#
|
125
|
+
# @api private
|
126
|
+
# @since 0.1.0
|
127
|
+
def apply(plugin_name, plugin_module)
|
128
|
+
plugin_name = indifferently_accessible_plugin_name(plugin_name)
|
129
|
+
|
130
|
+
if registered?(plugin_name)
|
131
|
+
raise(SmartCore::Initializer::AlreadyRegisteredPluginError, <<~ERROR_MESSAGE)
|
132
|
+
#{plugin_name} plugin already exists
|
133
|
+
ERROR_MESSAGE
|
134
|
+
end
|
135
|
+
|
136
|
+
plugin_set[plugin_name] = plugin_module
|
137
|
+
end
|
138
|
+
|
139
|
+
# @param plugin_name [Symbol, String]
|
140
|
+
# @return [SmartCore::Initializer::Plugins::Abstract]
|
141
|
+
#
|
142
|
+
# @raise [SmartCore::Initializer::UnregisteredPluginError]
|
143
|
+
#
|
144
|
+
# @api private
|
145
|
+
# @since 0.1.0
|
146
|
+
def fetch(plugin_name)
|
147
|
+
plugin_name = indifferently_accessible_plugin_name(plugin_name)
|
148
|
+
|
149
|
+
unless registered?(plugin_name)
|
150
|
+
raise(SmartCore::Initializer::UnregisteredPluginError, <<~ERROR_MESSAGE)
|
151
|
+
#{plugin_name} plugin is not registered
|
152
|
+
ERROR_MESSAGE
|
153
|
+
end
|
154
|
+
|
155
|
+
plugin_set[plugin_name]
|
156
|
+
end
|
157
|
+
|
158
|
+
# @param key [Symbol, String]
|
159
|
+
# @return [String]
|
160
|
+
#
|
161
|
+
# @api private
|
162
|
+
# @since 0.1.0
|
163
|
+
def indifferently_accessible_plugin_name(plugin_name)
|
164
|
+
plugin_name.to_s
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
module SmartCore::Initializer::Plugins::RegistryInterface
|
6
|
+
class << self
|
7
|
+
# @param base_module [Class, Module]
|
8
|
+
# @return [void]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
def extended(base_module)
|
13
|
+
base_module.instance_variable_set(
|
14
|
+
:@plugin_registry, SmartCore::Initializer::Plugins::Registry.new
|
15
|
+
)
|
16
|
+
base_module.instance_variable_set(
|
17
|
+
:@access_lock, SmartCore::Engine::Lock.new
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param plugin_name [Symbol, String]
|
23
|
+
# @return [void]
|
24
|
+
#
|
25
|
+
# @api public
|
26
|
+
# @since 0.1.0
|
27
|
+
def load(plugin_name)
|
28
|
+
thread_safe { plugin_registry[plugin_name].load! }
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Array<String>]
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
# @since 0.1.0
|
35
|
+
def loaded_plugins
|
36
|
+
thread_safe { plugin_registry.loaded.keys }
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Array<String>]
|
40
|
+
#
|
41
|
+
# @api public
|
42
|
+
# @since 0.1.0
|
43
|
+
def names
|
44
|
+
thread_safe { plugin_registry.names }
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param plugin_name [Symbol, String]
|
48
|
+
# @return [void]
|
49
|
+
#
|
50
|
+
# @api private
|
51
|
+
# @since 0.1.0
|
52
|
+
def register_plugin(plugin_name, plugin_module)
|
53
|
+
thread_safe { plugin_registry[plugin_name] = plugin_module }
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# @return [SmartCore::Initializer::Plugins::Registry]
|
59
|
+
#
|
60
|
+
# @api private
|
61
|
+
# @since 0.1.0
|
62
|
+
attr_reader :plugin_registry
|
63
|
+
|
64
|
+
# @return [SmartCore::Engine::Lock]
|
65
|
+
#
|
66
|
+
# @api private
|
67
|
+
# @since 0.1.0
|
68
|
+
attr_reader :access_lock
|
69
|
+
|
70
|
+
# @return [void]
|
71
|
+
#
|
72
|
+
# @api private
|
73
|
+
# @since 0.1.0
|
74
|
+
def thread_safe
|
75
|
+
access_lock.synchronize { yield if block_given? }
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Initializer::Plugins::ThyTypes < SmartCore::Initializer::Plugins::Abstract
|
6
|
+
class << self
|
7
|
+
# @return [void]
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 0.1.0
|
11
|
+
def install!
|
12
|
+
raise(
|
13
|
+
SmartCore::Initializer::UnresolvedPluginDependencyError,
|
14
|
+
'::Thy does not exist or "thy" gem is not loaded'
|
15
|
+
) unless const_defined?('::Thy')
|
16
|
+
|
17
|
+
# NOTE: require necessary dependencies
|
18
|
+
require 'date'
|
19
|
+
|
20
|
+
# NOTE: add thy-types type system implementation
|
21
|
+
require_relative 'thy_types/errors'
|
22
|
+
require_relative 'thy_types/thy_types'
|
23
|
+
|
24
|
+
# NOTE: register thy-types type system
|
25
|
+
SmartCore::Initializer::TypeSystem.register(
|
26
|
+
:thy_types, SmartCore::Initializer::TypeSystem::ThyTypes
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|