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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +36 -5
  4. data/CHANGELOG.md +23 -0
  5. data/Gemfile.lock +63 -43
  6. data/README.md +184 -26
  7. data/Rakefile +1 -1
  8. data/bin/rspec +54 -0
  9. data/gemfiles/with_external_deps.gemfile +7 -0
  10. data/gemfiles/with_external_deps.gemfile.lock +102 -0
  11. data/gemfiles/without_external_deps.gemfile +5 -0
  12. data/gemfiles/without_external_deps.gemfile.lock +100 -0
  13. data/lib/smart_core/initializer.rb +41 -35
  14. data/lib/smart_core/initializer/attribute.rb +12 -4
  15. data/lib/smart_core/initializer/attribute/factory.rb +47 -27
  16. data/lib/smart_core/initializer/attribute/parameters.rb +12 -4
  17. data/lib/smart_core/initializer/configuration.rb +33 -0
  18. data/lib/smart_core/initializer/constructor.rb +21 -8
  19. data/lib/smart_core/initializer/constructor/definer.rb +34 -11
  20. data/lib/smart_core/initializer/dsl.rb +27 -7
  21. data/lib/smart_core/initializer/errors.rb +44 -0
  22. data/lib/smart_core/initializer/functionality.rb +37 -0
  23. data/lib/smart_core/initializer/instance_attribute_accessing.rb +51 -0
  24. data/lib/smart_core/initializer/plugins.rb +17 -0
  25. data/lib/smart_core/initializer/plugins/abstract.rb +55 -0
  26. data/lib/smart_core/initializer/plugins/access_mixin.rb +47 -0
  27. data/lib/smart_core/initializer/plugins/registry.rb +166 -0
  28. data/lib/smart_core/initializer/plugins/registry_interface.rb +77 -0
  29. data/lib/smart_core/initializer/plugins/thy_types.rb +30 -0
  30. data/lib/smart_core/initializer/plugins/thy_types/errors.rb +11 -0
  31. data/lib/smart_core/initializer/plugins/thy_types/thy_types.rb +23 -0
  32. data/lib/smart_core/initializer/plugins/thy_types/thy_types/abstract_factory.rb +78 -0
  33. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation.rb +12 -0
  34. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/base.rb +9 -0
  35. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/cast.rb +21 -0
  36. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/valid.rb +16 -0
  37. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/validate.rb +19 -0
  38. data/lib/smart_core/initializer/settings.rb +49 -0
  39. data/lib/smart_core/initializer/settings/duplicator.rb +20 -0
  40. data/lib/smart_core/initializer/settings/type_system.rb +69 -0
  41. data/lib/smart_core/initializer/type_system.rb +16 -0
  42. data/lib/smart_core/initializer/type_system/interop.rb +103 -0
  43. data/lib/smart_core/initializer/type_system/interop/abstract_factory.rb +70 -0
  44. data/lib/smart_core/initializer/type_system/interop/aliasing.rb +72 -0
  45. data/lib/smart_core/initializer/type_system/interop/aliasing/alias_list.rb +141 -0
  46. data/lib/smart_core/initializer/type_system/interop/operation.rb +30 -0
  47. data/lib/smart_core/initializer/type_system/registry.rb +174 -0
  48. data/lib/smart_core/initializer/type_system/registry_interface.rb +102 -0
  49. data/lib/smart_core/initializer/type_system/smart_types.rb +48 -0
  50. data/lib/smart_core/initializer/type_system/smart_types/abstract_factory.rb +72 -0
  51. data/lib/smart_core/initializer/type_system/smart_types/operation.rb +13 -0
  52. data/lib/smart_core/initializer/type_system/smart_types/operation/base.rb +8 -0
  53. data/lib/smart_core/initializer/type_system/smart_types/operation/cast.rb +16 -0
  54. data/lib/smart_core/initializer/type_system/smart_types/operation/valid.rb +16 -0
  55. data/lib/smart_core/initializer/type_system/smart_types/operation/validate.rb +16 -0
  56. data/lib/smart_core/initializer/version.rb +2 -1
  57. data/smart_initializer.gemspec +13 -9
  58. metadata +68 -17
  59. data/lib/smart_core/initializer/attribute/init_extension.rb +0 -4
  60. data/lib/smart_core/initializer/type_aliasing.rb +0 -50
  61. 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