smart_initializer 0.1.0.alpha4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +36 -5
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile.lock +48 -31
  6. data/README.md +151 -22
  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 +99 -0
  11. data/gemfiles/without_external_deps.gemfile +5 -0
  12. data/gemfiles/without_external_deps.gemfile.lock +97 -0
  13. data/lib/smart_core/initializer.rb +38 -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/configurable_module.rb +27 -0
  18. data/lib/smart_core/initializer/configuration.rb +33 -0
  19. data/lib/smart_core/initializer/constructor.rb +9 -6
  20. data/lib/smart_core/initializer/constructor/definer.rb +34 -11
  21. data/lib/smart_core/initializer/dsl.rb +23 -6
  22. data/lib/smart_core/initializer/errors.rb +44 -0
  23. data/lib/smart_core/initializer/plugins.rb +17 -0
  24. data/lib/smart_core/initializer/plugins/abstract.rb +55 -0
  25. data/lib/smart_core/initializer/plugins/access_mixin.rb +47 -0
  26. data/lib/smart_core/initializer/plugins/registry.rb +166 -0
  27. data/lib/smart_core/initializer/plugins/registry_interface.rb +77 -0
  28. data/lib/smart_core/initializer/plugins/thy_types.rb +30 -0
  29. data/lib/smart_core/initializer/plugins/thy_types/errors.rb +11 -0
  30. data/lib/smart_core/initializer/plugins/thy_types/thy_types.rb +23 -0
  31. data/lib/smart_core/initializer/plugins/thy_types/thy_types/abstract_factory.rb +78 -0
  32. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation.rb +12 -0
  33. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/base.rb +9 -0
  34. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/cast.rb +21 -0
  35. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/valid.rb +16 -0
  36. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/validate.rb +19 -0
  37. data/lib/smart_core/initializer/settings.rb +49 -0
  38. data/lib/smart_core/initializer/settings/duplicator.rb +20 -0
  39. data/lib/smart_core/initializer/settings/type_system.rb +69 -0
  40. data/lib/smart_core/initializer/type_system.rb +16 -0
  41. data/lib/smart_core/initializer/type_system/interop.rb +103 -0
  42. data/lib/smart_core/initializer/type_system/interop/abstract_factory.rb +70 -0
  43. data/lib/smart_core/initializer/type_system/interop/aliasing.rb +72 -0
  44. data/lib/smart_core/initializer/type_system/interop/aliasing/alias_list.rb +141 -0
  45. data/lib/smart_core/initializer/type_system/interop/operation.rb +30 -0
  46. data/lib/smart_core/initializer/type_system/registry.rb +174 -0
  47. data/lib/smart_core/initializer/type_system/registry_interface.rb +102 -0
  48. data/lib/smart_core/initializer/type_system/smart_types.rb +48 -0
  49. data/lib/smart_core/initializer/type_system/smart_types/abstract_factory.rb +72 -0
  50. data/lib/smart_core/initializer/type_system/smart_types/operation.rb +13 -0
  51. data/lib/smart_core/initializer/type_system/smart_types/operation/base.rb +8 -0
  52. data/lib/smart_core/initializer/type_system/smart_types/operation/cast.rb +16 -0
  53. data/lib/smart_core/initializer/type_system/smart_types/operation/valid.rb +16 -0
  54. data/lib/smart_core/initializer/type_system/smart_types/operation/validate.rb +16 -0
  55. data/lib/smart_core/initializer/version.rb +1 -1
  56. data/smart_initializer.gemspec +13 -9
  57. metadata +67 -17
  58. data/lib/smart_core/initializer/attribute/init_extension.rb +0 -4
  59. data/lib/smart_core/initializer/type_aliasing.rb +0 -50
  60. data/lib/smart_core/initializer/type_aliasing/alias_list.rb +0 -101
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.1.0
5
+ class SmartCore::Initializer::TypeSystem::Interop::Aliasing::AliasList
6
+ # @param interop_klass [Class<SmartCore::Initializer::TypeSystem::Interop>]
7
+ # @return [void]
8
+ #
9
+ # @api private
10
+ # @since 0.1.0
11
+ def initialize(interop_klass)
12
+ @interop_klass = interop_klass
13
+ @list = {}
14
+ @lock = SmartCore::Engine::Lock.new
15
+ end
16
+
17
+ # @return [Array<String>]
18
+ #
19
+ # @api private
20
+ # @since 0.1.0
21
+ def keys
22
+ thread_safe { registered_aliases }
23
+ end
24
+
25
+ # @return [Hash<String,Any>]
26
+ #
27
+ # @api private
28
+ # @since 0.1.0
29
+ def to_h
30
+ thread_safe { transform_to_hash }
31
+ end
32
+ alias_method :to_hash, :to_h
33
+
34
+ # @param alias_name [String, Symbol]
35
+ # @param type [Any]
36
+ # @return [void]
37
+ #
38
+ # @api private
39
+ # @since 0.1.0
40
+ def associate(alias_name, type)
41
+ interop_klass.prevent_incompatible_type!(type)
42
+ thread_safe { set_alias(alias_name, type) }
43
+ end
44
+
45
+ # @param alias_name [String, Symbol]
46
+ # @return [Any]
47
+ #
48
+ # @api private
49
+ # @since 0.1.0
50
+ def resolve(alias_name)
51
+ thread_safe { get_alias(alias_name) }
52
+ end
53
+
54
+ private
55
+
56
+ # @return [Hash<String,Any>]
57
+ #
58
+ # @api private
59
+ # @since 0.1.0
60
+ attr_reader :list
61
+
62
+ # @return [Class<SmartCore::Initializer::TypeSystem::Interop>]
63
+ #
64
+ # @api private
65
+ # @since 0.1.0
66
+ attr_reader :interop_klass
67
+
68
+ # @param block [Block]
69
+ # @return [Any]
70
+ #
71
+ # @api private
72
+ # @since 0.1.0
73
+ def thread_safe(&block)
74
+ @lock.synchronize(&block)
75
+ end
76
+
77
+ # @param alias_name [String, Symbol]
78
+ # @param type [Any]
79
+ # @return [void]
80
+ #
81
+ # @api private
82
+ # @since 0.1.0
83
+ def set_alias(alias_name, type)
84
+ alias_name = normalized_alias(alias_name)
85
+
86
+ if list.key?(alias_name)
87
+ ::Warning.warn(
88
+ "[#{interop_klass.name}] Shadowing of the already existing \"#{alias_name}\" type alias."
89
+ )
90
+ end
91
+
92
+ list[alias_name] = type
93
+ end
94
+
95
+ # @param alias_name [String, Symbol]
96
+ # @return [Any]
97
+ #
98
+ # @api private
99
+ # @since 0.1.0
100
+ def get_alias(alias_name)
101
+ alias_name = normalized_alias(alias_name)
102
+
103
+ begin
104
+ list.fetch(alias_name)
105
+ rescue ::KeyError
106
+ raise(SmartCore::Initializer::TypeAliasNotFoundError, <<~ERROR_MESSAGE)
107
+ Alias with name "#{alias_name}" not found.
108
+ ERROR_MESSAGE
109
+ end
110
+ end
111
+
112
+ # @param alias_name [String, Symbol]
113
+ # @return [String]
114
+ #
115
+ # @api private
116
+ # @since 0.1.0
117
+ def normalized_alias(alias_name)
118
+ raise(
119
+ SmartCore::Initializer::ArgumentError,
120
+ 'Type alias should be a type of string or symbol'
121
+ ) unless alias_name.is_a?(String) || alias_name.is_a?(Symbol)
122
+
123
+ alias_name.to_s
124
+ end
125
+
126
+ # @return [Hash<String,Any>]
127
+ #
128
+ # @api private
129
+ # @since 0.1.0
130
+ def transform_to_hash
131
+ list.to_h
132
+ end
133
+
134
+ # @return [Array<String>]
135
+ #
136
+ # @api private
137
+ # @since 0.1.0
138
+ def registered_aliases
139
+ list.keys
140
+ end
141
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @abstract
4
+ # @api private
5
+ # @since 0.1.0
6
+ class SmartCore::Initializer::TypeSystem::Interop::Operation
7
+ # @param type [Any]
8
+ # @return [void]
9
+ #
10
+ # @api private
11
+ # @since 0.1.0
12
+ def initialize(type)
13
+ @type = type
14
+ end
15
+
16
+ # @param value [Any]
17
+ # @return [Any]
18
+ #
19
+ # @api private
20
+ # @since 0.1.0
21
+ def call(value); end
22
+
23
+ private
24
+
25
+ # @return [Any]
26
+ #
27
+ # @api private
28
+ # @since 0.1.0
29
+ attr_reader :type
30
+ end
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.1.0
5
+ class SmartCore::Initializer::TypeSystem::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
+ @systems = {}
15
+ @lock = SmartCore::Engine::Lock.new
16
+ end
17
+
18
+ # @param system_identifier [String, Symbol]
19
+ # @param interop_klass [Class<SmartCore::Initializer::TypeSystem::Interop>]
20
+ # @return [void]
21
+ #
22
+ # @api private
23
+ # @since 0.1.0
24
+ def register(system_identifier, interop_klass)
25
+ thread_safe { apply(system_identifier, interop_klass) }
26
+ end
27
+
28
+ # @param system_identifier [String, Symbol]
29
+ # @return [Class<SmartCore::Initializer::TypeSystem::Interop>]
30
+ #
31
+ # @api private
32
+ # @since 0.1.0
33
+ def resolve(system_identifier)
34
+ thread_safe { fetch(system_identifier) }
35
+ end
36
+
37
+ # @return [Array<String>]
38
+ #
39
+ # @api private
40
+ # @since 0.1.0
41
+ def names
42
+ thread_safe { system_names }
43
+ end
44
+
45
+ # @return [Array<Class<SmartCore::Initializer::TypeSystem::Interop>>]
46
+ #
47
+ # @api private
48
+ # @since 0.1.0
49
+ def interops
50
+ thread_safe { system_interops }
51
+ end
52
+
53
+ # @param block [Block]
54
+ # @yield [system_name, system_interop]
55
+ # @yieldparam system_name [String]
56
+ # @yieldparam system_interop [Class<SmartCore::Initializer::TypeSystem::Interop>]
57
+ # @return [Enumerable]
58
+ #
59
+ # @api private
60
+ # @since 0.1.0
61
+ def each(&block)
62
+ thread_safe { iterate(&block) }
63
+ end
64
+
65
+ # @return [Hash<String,Class<SmartCore::Initializer::TypeSystem::Interop>]
66
+ #
67
+ # @api private
68
+ # @since 0.1.0
69
+ def to_h
70
+ thread_safe { systems.dup }
71
+ end
72
+ alias_method :to_hash, :to_h
73
+
74
+ private
75
+
76
+ # @return [Hash<String,Class<SmartCore::Initializer::TypeSystem::Interop>]
77
+ #
78
+ # @api private
79
+ # @since 0.1.0
80
+ attr_reader :systems
81
+
82
+ # @return [Array<String>]
83
+ #
84
+ # @pai private
85
+ # @since 0.1.0
86
+ def system_names
87
+ systems.keys
88
+ end
89
+
90
+ # @return [Array<Class<SmartCore::Initializer::TypeSystem::Interop>>]
91
+ #
92
+ # @api private
93
+ # @since 0.1.0
94
+ def system_interops
95
+ systems.values
96
+ end
97
+
98
+ # @param block [Block]
99
+ # @yield [system_name, system_interop]
100
+ # @yieldparam system_name [String]
101
+ # @yieldparam system_interop [Class<SmartCore::Initializer::TypeSystem::Interop>]
102
+ # @return [Enumerable]
103
+ #
104
+ # @api private
105
+ # @since 0.1.0
106
+ def iterate(&block)
107
+ block_given? ? systems.each_pair(&block) : systems.each_pair
108
+ end
109
+
110
+ # @param system_identifier [String, Symbol]
111
+ # @param interop_klass [Class<SmartCore::Initializer::TypeSystem::Interop>]
112
+ # @return [void]
113
+ #
114
+ # @api private
115
+ # @since 0.1.0
116
+ def apply(system_identifier, interop_klass)
117
+ prevent_incorrect_system_interop!(interop_klass)
118
+ identifier = indifferently_accessible_identifier(system_identifier)
119
+ systems[identifier] = interop_klass
120
+ end
121
+
122
+ # @param system_identifier [String, Symbol]
123
+ # @return [Class<SmartCore::Initializer::TypeSystem::Interop>]
124
+ #
125
+ # @raise [SmartCore::Initializer::UnsupportedTypeSystemError]
126
+ #
127
+ # @api private
128
+ # @since 0.1.0
129
+ def fetch(system_identifier)
130
+ identifier = indifferently_accessible_identifier(system_identifier)
131
+
132
+ begin
133
+ systems.fetch(identifier)
134
+ rescue ::KeyError
135
+ raise(SmartCore::Initializer::UnsupportedTypeSystemError, <<~ERROR_MESSAGE)
136
+ "#{identifier}" type system is not supported.
137
+ ERROR_MESSAGE
138
+ end
139
+ end
140
+
141
+ # @param interop_klass [Class<SMartCore::Initializer::TypeSystem::Interop>]
142
+ # @return [void]
143
+ #
144
+ # @raise [SmartCore::Initializer::IncorrectTypeSystemInteropError]
145
+ #
146
+ # @api private
147
+ # @since 0.1.0
148
+ def prevent_incorrect_system_interop!(interop_klass)
149
+ unless interop_klass.is_a?(Class) && interop_klass < SmartCore::Initializer::TypeSystem::Interop
150
+ raise(
151
+ SmartCore::Initializer::IncorrectTypeSystemInteropError,
152
+ 'Incorrect type system interop class.'
153
+ )
154
+ end
155
+ end
156
+
157
+ # @param system_identifier [String, Symbol]
158
+ # @return [String]
159
+ #
160
+ # @api private
161
+ # @since 0.1.0
162
+ def indifferently_accessible_identifier(system_identifier)
163
+ system_identifier.to_s.clone.tap(&:freeze)
164
+ end
165
+
166
+ # @param block [Block]
167
+ # @return [Any]
168
+ #
169
+ # @api private
170
+ # @since 0.1.0
171
+ def thread_safe(&block)
172
+ @lock.synchronize(&block)
173
+ end
174
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.1.0
5
+ module SmartCore::Initializer::TypeSystem::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
+ :@registry, SmartCore::Initializer::TypeSystem::Registry.new
15
+ )
16
+ base_module.instance_variable_set(
17
+ :@access_lock, SmartCore::Engine::Lock.new
18
+ )
19
+ end
20
+ end
21
+
22
+ # @option system_identifier [String, Symbol]
23
+ # @option type [Any]
24
+ # @return [SmartCore::Initializer::TypeSystem::Interop]
25
+ #
26
+ # @api private
27
+ # @since 0.1.0
28
+ def build_interop(system: system_identifier, type: type_object)
29
+ thread_safe { registry.resolve(system_identifier).create(type_object) }
30
+ end
31
+
32
+ # @param identifier [String, Symbol]
33
+ # @param interop_klass [Class<SmartCore::Initializer::TypeSystem::Interop>]
34
+ # @return [void]
35
+ #
36
+ # @api private
37
+ # @since 0.1.0
38
+ def register(identifier, interop_klass)
39
+ thread_safe { registry.register(identifier, interop_klass) }
40
+ end
41
+
42
+ # @param identifier [String, Symbol]
43
+ # @return [Class<SmartCore::Initializer::TypeSystem::Interop>]
44
+ #
45
+ # @api private
46
+ # @since 0.1.0
47
+ def resolve(identifier)
48
+ thread_safe { registry.resolve(identifier) }
49
+ end
50
+ alias_method :[], :resolve
51
+
52
+ # @return [Array<String>]
53
+ #
54
+ # @api public
55
+ # @since 0.1.0
56
+ def names
57
+ thread_safe { registry.names }
58
+ end
59
+
60
+ # @return [Array<Class<SmartCore::Initializer::TypeSystem::Interop>>]
61
+ #
62
+ # @api public
63
+ # @since 0.1.0
64
+ def systems
65
+ thread_safe { registry.to_h }
66
+ end
67
+
68
+ # @param block [Block]
69
+ # @yield [system_name, system_interop]
70
+ # @yieldparam system_name [String]
71
+ # @yieldparam system_interop [Class<SmartCore::Initializer::TypeSystem::Interop>]
72
+ # @return [Enumerable]
73
+ #
74
+ # @api public
75
+ # @since 0.1.0
76
+ def each(&block)
77
+ thread_safe { registry.each(&block) }
78
+ end
79
+
80
+ private
81
+
82
+ # @return [SmartCore::Initializer::TypeSystem::Registry]
83
+ #
84
+ # @api private
85
+ # @since 0.1.0
86
+ attr_reader :registry
87
+
88
+ # @return [SmartCore::Engine::Lock]
89
+ #
90
+ # @api private
91
+ # @since 0.1.0
92
+ attr_reader :access_lock
93
+
94
+ # @param block [Block]
95
+ # @return [Any]
96
+ #
97
+ # @api pribate
98
+ # @since 0.1.0
99
+ def thread_safe(&block)
100
+ access_lock.synchronize(&block)
101
+ end
102
+ end