smart_initializer 0.1.0.alpha3 → 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/.rubocop.yml +1 -1
- data/.travis.yml +36 -5
- data/CHANGELOG.md +19 -0
- data/Gemfile.lock +63 -43
- data/README.md +227 -11
- 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 +44 -34
- data/lib/smart_core/initializer/attribute.rb +12 -5
- 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 +35 -8
- data/lib/smart_core/initializer/{attribute → constructor}/definer.rb +64 -12
- data/lib/smart_core/initializer/dsl.rb +49 -10
- data/lib/smart_core/initializer/dsl/inheritance.rb +1 -0
- data/lib/smart_core/initializer/errors.rb +44 -0
- data/lib/smart_core/initializer/extensions.rb +9 -0
- data/lib/smart_core/initializer/extensions/abstract.rb +8 -0
- data/lib/smart_core/initializer/extensions/ext_init.rb +31 -0
- data/lib/smart_core/initializer/extensions/list.rb +74 -0
- data/lib/smart_core/initializer/functionality.rb +36 -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 +73 -17
- 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,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
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Initializer::TypeSystem
|
4
|
+
# @api public
|
5
|
+
# @since 0.1.0
|
6
|
+
class ThyTypes < Interop
|
7
|
+
require_relative 'thy_types/abstract_factory'
|
8
|
+
require_relative 'thy_types/operation'
|
9
|
+
|
10
|
+
type_alias(:any, AbstractFactory.generic_type_object)
|
11
|
+
type_alias(:nil, ::Thy::Types::Nil)
|
12
|
+
type_alias(:string, ::Thy::Types::String)
|
13
|
+
type_alias(:symbol, ::Thy::Types::Symbol)
|
14
|
+
type_alias(:integer, ::Thy::Types::Integer)
|
15
|
+
type_alias(:float, ::Thy::Types::Float)
|
16
|
+
type_alias(:numeric, ::Thy::Types::Numeric)
|
17
|
+
type_alias(:boolean, ::Thy::Types::Boolean)
|
18
|
+
type_alias(:time, ::Thy::Types::Time)
|
19
|
+
type_alias(:date_time, ::Thy::Types::DateTime)
|
20
|
+
type_alias(:untyped_array, ::Thy::Types::UntypedArray)
|
21
|
+
type_alias(:untyped_hash, ::Thy::Types::UntypedHash)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Initializer::TypeSystem
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class ThyTypes::AbstractFactory < Interop::AbstractFactory
|
7
|
+
# @return [Thy::Type]
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 0.1.0
|
11
|
+
GENERIC_TYPE = ::Thy::Type.new { true }
|
12
|
+
|
13
|
+
class << self
|
14
|
+
# @param type [Thy::Type, #check]
|
15
|
+
# @return [void]
|
16
|
+
#
|
17
|
+
# @raise [SmartCore::Initializer::IncorrectTypeObjectError]
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
# @since 0.1.0
|
21
|
+
def prevent_incompatible_type!(type)
|
22
|
+
unless type.respond_to?(:check) || type.is_a?(::Thy::Type)
|
23
|
+
raise(
|
24
|
+
SmartCore::Initializer::IncorrectTypeObjectError,
|
25
|
+
'Incorrect Thy::Type primitive ' \
|
26
|
+
'(type object should respond to :check method)'
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param type [Thy::Type, #check]
|
32
|
+
# @return [SmartCore::Initializer::TypeSystem::ThyTypes::Operation::Valid]
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
# @since 0.1.0
|
36
|
+
def build_valid_operation(type)
|
37
|
+
ThyTypes::Operation::Valid.new(type)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Thy::Type, #check]
|
41
|
+
#
|
42
|
+
# @api private
|
43
|
+
# @since 0.1.0
|
44
|
+
def generic_type_object
|
45
|
+
GENERIC_TYPE
|
46
|
+
end
|
47
|
+
|
48
|
+
# @param type [Thy::Type, #check]
|
49
|
+
# @return [SmartCore::Initializer::TypeSystem::ThyTypes::Operation::Validate]
|
50
|
+
#
|
51
|
+
# @api private
|
52
|
+
# @since 0.1.0
|
53
|
+
def build_validate_operation(type)
|
54
|
+
ThyTypes::Operation::Validate.new(type)
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param type [Thy::Type, #check]
|
58
|
+
# @return [SmartCore::Initializer::TypeSystem::ThyTypes::Operation::Cast]
|
59
|
+
#
|
60
|
+
# @api private
|
61
|
+
# @since 0.1.0
|
62
|
+
def build_cast_operation(type)
|
63
|
+
ThyTypes::Operation::Cast.new(type)
|
64
|
+
end
|
65
|
+
|
66
|
+
# @param valid_op [SmartCore::Initializer::TypeSystem::ThyTypes::Operation::Valid]
|
67
|
+
# @param valid_op [SmartCore::Initializer::TypeSystem::ThyTypes::Operation::Validate]
|
68
|
+
# @param valid_op [SmartCore::Initializer::TypeSystem::ThyTypes::Operation::Cast]
|
69
|
+
# @return [SmartCore::Initializer::TypeSystem::ThyTypes]
|
70
|
+
#
|
71
|
+
# @api private
|
72
|
+
# @since 0.1.0
|
73
|
+
def build_interop(valid_op, validate_op, cast_op)
|
74
|
+
ThyTypes.new(valid_op, validate_op, cast_op)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Initializer::TypeSystem
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
module ThyTypes::Operation
|
7
|
+
require_relative 'operation/base'
|
8
|
+
require_relative 'operation/valid'
|
9
|
+
require_relative 'operation/validate'
|
10
|
+
require_relative 'operation/cast'
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Initializer::TypeSystem::ThyTypes::Operation
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class Cast < Base
|
7
|
+
# @param value [Any]
|
8
|
+
# @return [void]
|
9
|
+
#
|
10
|
+
# @raise [SmartCore::Initializer::TypeCastingUnsupportedError]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.1.0
|
14
|
+
def call(value)
|
15
|
+
raise(
|
16
|
+
SmartCore::Initializer::TypeCastingUnsupportedError,
|
17
|
+
'ThyTypes type system has no support for type casting.'
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Initializer::TypeSystem::ThyTypes::Operation
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class Valid < Base
|
7
|
+
# @param value [Any]
|
8
|
+
# @return [Boolean]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
def call(value)
|
13
|
+
type.check(value).success?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Initializer::TypeSystem::ThyTypes::Operation
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class Validate < Base
|
7
|
+
# @param value [Any]
|
8
|
+
# @return [void]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
def call(value)
|
13
|
+
raise(
|
14
|
+
SmartCore::Initializer::ThyTypeValidationError,
|
15
|
+
"Thy::Types validation error: (get #{value.inspect} for type #{type.inspect}"
|
16
|
+
) unless type.check(value).success?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Initializer::Settings
|
6
|
+
require_relative 'settings/type_system'
|
7
|
+
require_relative 'settings/duplicator'
|
8
|
+
|
9
|
+
# @return [void]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
# @since 0.1.0
|
13
|
+
def initialize
|
14
|
+
@type_system = TypeSystem.new
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Any]
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
# @since 0.1.0
|
21
|
+
def generic_type_object
|
22
|
+
@type_system.generic_type_object
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Symbol]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.1.0
|
29
|
+
def type_system
|
30
|
+
@type_system.resolve
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param value [String, System]
|
34
|
+
# @return [void]
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
# @since 0.1.0
|
38
|
+
def type_system=(value)
|
39
|
+
@type_system.assign(value)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [SmartCore::Initializer::Settings]
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
# @since 0.1.0
|
46
|
+
def dup
|
47
|
+
Duplicator.duplicate(self)
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
module SmartCore::Initializer::Settings::Duplicator
|
6
|
+
class << self
|
7
|
+
# @param settings [SmartCore::Initializer::Settings]
|
8
|
+
# @return [SmartCore::Initializer::Settings]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
def duplicate(settings)
|
13
|
+
SmartCore::Initializer::Settings.new.tap do |new_instance|
|
14
|
+
type_system = settings.instance_variable_get(:@type_system).dup
|
15
|
+
|
16
|
+
new_instance.instance_variable_set(:@type_system, type_system)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Initializer::Settings::TypeSystem
|
6
|
+
# @return [void]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.1.0
|
10
|
+
def initialize
|
11
|
+
@type_system = nil
|
12
|
+
@lock = SmartCore::Engine::Lock.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Any]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
# @since 0.1.0
|
19
|
+
def generic_type_object
|
20
|
+
thread_safe do
|
21
|
+
SmartCore::Initializer::TypeSystem.resolve(resolve).generic_type_object
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Symbol]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.1.0
|
29
|
+
def resolve
|
30
|
+
thread_safe do
|
31
|
+
@type_system || SmartCore::Initializer::Configuration.config[:default_type_system]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param value [String, Symbol]
|
36
|
+
# @return [void]
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
# @since 0.1.0
|
40
|
+
def assign(value)
|
41
|
+
thread_safe do
|
42
|
+
SmartCore::Initializer::TypeSystem.resolve(value) # NOTE: type system existence validation
|
43
|
+
@type_system = value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [SmartCore::Initializer::Settings::TypeSystem]
|
48
|
+
#
|
49
|
+
# @api private
|
50
|
+
# @since 0.1.0
|
51
|
+
def dup
|
52
|
+
thread_safe do
|
53
|
+
self.class.new.tap do |duplicate|
|
54
|
+
duplicate.instance_variable_set(:@type_system, @type_system)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# @param block [Block]
|
62
|
+
# @return [Any]
|
63
|
+
#
|
64
|
+
# @api private
|
65
|
+
# @since 0.1.0
|
66
|
+
def thread_safe(&block)
|
67
|
+
@lock.synchronize(&block)
|
68
|
+
end
|
69
|
+
end
|