smart_initializer 0.1.0.alpha2 → 0.3.0

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +36 -5
  4. data/CHANGELOG.md +15 -0
  5. data/Gemfile.lock +63 -43
  6. data/README.md +263 -11
  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 +44 -28
  14. data/lib/smart_core/initializer/attribute.rb +12 -5
  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 +60 -23
  19. data/lib/smart_core/initializer/{attribute → constructor}/definer.rb +64 -12
  20. data/lib/smart_core/initializer/dsl.rb +47 -10
  21. data/lib/smart_core/initializer/dsl/inheritance.rb +1 -0
  22. data/lib/smart_core/initializer/errors.rb +44 -0
  23. data/lib/smart_core/initializer/extensions.rb +9 -0
  24. data/lib/smart_core/initializer/extensions/abstract.rb +8 -0
  25. data/lib/smart_core/initializer/extensions/ext_init.rb +31 -0
  26. data/lib/smart_core/initializer/extensions/list.rb +74 -0
  27. data/lib/smart_core/initializer/functionality.rb +36 -0
  28. data/lib/smart_core/initializer/instance_attribute_accessing.rb +51 -0
  29. data/lib/smart_core/initializer/plugins.rb +17 -0
  30. data/lib/smart_core/initializer/plugins/abstract.rb +55 -0
  31. data/lib/smart_core/initializer/plugins/access_mixin.rb +47 -0
  32. data/lib/smart_core/initializer/plugins/registry.rb +166 -0
  33. data/lib/smart_core/initializer/plugins/registry_interface.rb +77 -0
  34. data/lib/smart_core/initializer/plugins/thy_types.rb +30 -0
  35. data/lib/smart_core/initializer/plugins/thy_types/errors.rb +11 -0
  36. data/lib/smart_core/initializer/plugins/thy_types/thy_types.rb +23 -0
  37. data/lib/smart_core/initializer/plugins/thy_types/thy_types/abstract_factory.rb +78 -0
  38. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation.rb +12 -0
  39. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/base.rb +9 -0
  40. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/cast.rb +21 -0
  41. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/valid.rb +16 -0
  42. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/validate.rb +19 -0
  43. data/lib/smart_core/initializer/settings.rb +49 -0
  44. data/lib/smart_core/initializer/settings/duplicator.rb +20 -0
  45. data/lib/smart_core/initializer/settings/type_system.rb +69 -0
  46. data/lib/smart_core/initializer/type_system.rb +16 -0
  47. data/lib/smart_core/initializer/type_system/interop.rb +103 -0
  48. data/lib/smart_core/initializer/type_system/interop/abstract_factory.rb +70 -0
  49. data/lib/smart_core/initializer/type_system/interop/aliasing.rb +72 -0
  50. data/lib/smart_core/initializer/type_system/interop/aliasing/alias_list.rb +141 -0
  51. data/lib/smart_core/initializer/type_system/interop/operation.rb +30 -0
  52. data/lib/smart_core/initializer/type_system/registry.rb +174 -0
  53. data/lib/smart_core/initializer/type_system/registry_interface.rb +102 -0
  54. data/lib/smart_core/initializer/type_system/smart_types.rb +48 -0
  55. data/lib/smart_core/initializer/type_system/smart_types/abstract_factory.rb +72 -0
  56. data/lib/smart_core/initializer/type_system/smart_types/operation.rb +13 -0
  57. data/lib/smart_core/initializer/type_system/smart_types/operation/base.rb +8 -0
  58. data/lib/smart_core/initializer/type_system/smart_types/operation/cast.rb +16 -0
  59. data/lib/smart_core/initializer/type_system/smart_types/operation/valid.rb +16 -0
  60. data/lib/smart_core/initializer/type_system/smart_types/operation/validate.rb +16 -0
  61. data/lib/smart_core/initializer/version.rb +2 -1
  62. data/smart_initializer.gemspec +13 -9
  63. metadata +73 -17
  64. data/lib/smart_core/initializer/type_aliasing.rb +0 -50
  65. 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,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SmartCore::Initializer
4
+ # @api public
5
+ # @since 0.1.0
6
+ ThyTypesError = Class.new(SmartCore::Initializer::Error)
7
+
8
+ # @api public
9
+ # @since 0.1.0
10
+ ThyTypeValidationError = Class.new(ThyTypesError)
11
+ 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,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SmartCore::Initializer::TypeSystem
4
+ # @abstract
5
+ # @api private
6
+ # @since 0.1.0
7
+ class ThyTypes::Operation::Base < Interop::Operation
8
+ end
9
+ 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