smart_core 0.6.0 → 0.7.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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -1
  3. data/.rubocop.yml +1 -1
  4. data/.travis.yml +5 -8
  5. data/CHANGELOG.md +5 -0
  6. data/README.md +14 -4
  7. data/lib/smart_core.rb +2 -2
  8. data/lib/smart_core/container.rb +49 -56
  9. data/lib/smart_core/container/arbitary_lock.rb +22 -0
  10. data/lib/smart_core/container/definition_dsl.rb +105 -55
  11. data/lib/smart_core/container/{command_set.rb → definition_dsl/command_set.rb} +20 -26
  12. data/lib/smart_core/container/definition_dsl/commands.rb +12 -0
  13. data/lib/smart_core/container/{commands → definition_dsl/commands}/base.rb +3 -3
  14. data/lib/smart_core/container/definition_dsl/commands/definition/compose.rb +46 -0
  15. data/lib/smart_core/container/definition_dsl/commands/definition/namespace.rb +51 -0
  16. data/lib/smart_core/container/{commands → definition_dsl/commands/definition}/register.rb +13 -25
  17. data/lib/smart_core/container/definition_dsl/commands/instantiation/compose.rb +50 -0
  18. data/lib/smart_core/container/definition_dsl/commands/instantiation/freeze_state.rb +24 -0
  19. data/lib/smart_core/container/dependency_compatability.rb +3 -3
  20. data/lib/smart_core/container/dependency_compatability/definition.rb +42 -0
  21. data/lib/smart_core/container/dependency_compatability/general.rb +61 -0
  22. data/lib/smart_core/container/dependency_compatability/registry.rb +28 -29
  23. data/lib/smart_core/container/dependency_resolver.rb +9 -4
  24. data/lib/smart_core/container/entities.rb +11 -0
  25. data/lib/smart_core/container/{entity.rb → entities/base.rb} +7 -7
  26. data/lib/smart_core/container/entities/dependency.rb +38 -0
  27. data/lib/smart_core/container/entities/dependency_builder.rb +50 -0
  28. data/lib/smart_core/container/entities/namespace.rb +73 -0
  29. data/lib/smart_core/container/entities/namespace_builder.rb +41 -0
  30. data/lib/smart_core/container/errors.rb +43 -0
  31. data/lib/smart_core/container/key_guard.rb +5 -5
  32. data/lib/smart_core/container/mixin.rb +20 -16
  33. data/lib/smart_core/container/registry.rb +224 -201
  34. data/lib/smart_core/container/registry_builder.rb +38 -5
  35. data/lib/smart_core/{exceptions.rb → errors.rb} +0 -0
  36. data/lib/smart_core/operation.rb +3 -1
  37. data/lib/smart_core/operation/{custom.rb → callback.rb} +7 -7
  38. data/lib/smart_core/operation/result.rb +1 -1
  39. data/lib/smart_core/operation/result_interface.rb +3 -3
  40. data/lib/smart_core/version.rb +1 -1
  41. data/smart_core.gemspec +6 -5
  42. metadata +28 -38
  43. data/lib/smart_core/container/command_definer.rb +0 -117
  44. data/lib/smart_core/container/commands.rb +0 -9
  45. data/lib/smart_core/container/commands/namespace.rb +0 -53
  46. data/lib/smart_core/container/dependency.rb +0 -44
  47. data/lib/smart_core/container/dependency_builder.rb +0 -48
  48. data/lib/smart_core/container/dependency_compatability/abstract.rb +0 -59
  49. data/lib/smart_core/container/dependency_compatability/command_set.rb +0 -35
  50. data/lib/smart_core/container/exceptions.rb +0 -31
  51. data/lib/smart_core/container/memoized_dependency.rb +0 -28
  52. data/lib/smart_core/container/namespace.rb +0 -51
@@ -1,36 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module SmartCore::Container::DependencyCompatability
4
- # @api private
5
- # @since 0.5.0
6
- class Registry < Abstract
7
- class << self
8
- # @param registry [SmartCore::Container::Regsitry]
9
- # @param dependency_name [String]
10
- # @return [Boolean]
11
- #
12
- # @api private
13
- # @since 0.5.0
14
- def potential_namespace_overlap?(registry, dependency_name)
15
- registry.any? do |registered_dependency|
16
- next unless registered_dependency.is_a?(SmartCore::Container::Namespace)
17
- # NOTE: registered_dependency is a namespace
18
- registered_dependency.external_name == dependency_name
19
- end
3
+ # @api private
4
+ # @since 0.7.0
5
+ module SmartCore::Container::DependencyCompatability::Registry
6
+ class << self
7
+ # @since 0.7.0
8
+ include SmartCore::Container::DependencyCompatability::General
9
+
10
+ # @param registry [SmartCore::Container::Registry]
11
+ # @param dependency_name [String, Symbol]
12
+ # @return [Boolean]
13
+ #
14
+ # @api private
15
+ # @since 0.7.0
16
+ def potential_namespace_overlap?(registry, dependency_name)
17
+ registry.any? do |(entity_name, entity)|
18
+ next unless entity.is_a?(SmartCore::Container::Entities::Namespace)
19
+ entity.namespace_name == dependency_name
20
20
  end
21
+ end
21
22
 
22
- # @param registry [SmartCore::Container::Regsitry]
23
- # @param namespace_name [String]
24
- # @return [Boolean]
25
- #
26
- # @api private
27
- # @since 0.5.0
28
- def potential_dependency_overlap?(registry, namespace_name)
29
- registry.any? do |registered_dependency|
30
- next unless registered_dependency.is_a?(SmartCore::Container::Dependency)
31
- # NOTE: registered_dependency is a dependency/memoized dependency
32
- registered_dependency.external_name == namespace_name
33
- end
23
+ # @param registry [SmartCore::Container::Registry]
24
+ # @param namespace_name [String, Symbol]
25
+ # @return [Boolean]
26
+ #
27
+ # @api private
28
+ # @since 0.7.0
29
+ def potential_dependency_overlap?(registry, namespace_name)
30
+ registry.any? do |(entity_name, entity)|
31
+ next unless entity.is_a?(SmartCore::Container::Entities::Dependency)
32
+ entity.dependency_name == namespace_name
34
33
  end
35
34
  end
36
35
  end
@@ -1,16 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.5.0
4
+ # @since 0.7.0
5
5
  module SmartCore::Container::DependencyResolver
6
6
  class << self
7
7
  # @param registry [SmartCore::Container::Registry]
8
- # @return [Any]
8
+ # @param dependency_path [String, Symbol]
9
+ # @return [SmartCore::Container, Any]
10
+ #
11
+ # @see SmartCore::Container::Registry#resolve
12
+ # @see SmartCore::Container::Entities::Namespace#resolve
13
+ # @see SmartCore::Container::Entities::Dependency#resolve
9
14
  #
10
15
  # @api private
11
- # @since 0.5.0
16
+ # @since 0.7.0
12
17
  def resolve(registry, dependency_path)
13
- registry.resolve(dependency_path).call
18
+ registry.resolve(dependency_path).resolve
14
19
  end
15
20
  end
16
21
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.7.0
5
+ module SmartCore::Container::Entities
6
+ require_relative 'entities/base'
7
+ require_relative 'entities/dependency'
8
+ require_relative 'entities/dependency_builder'
9
+ require_relative 'entities/namespace'
10
+ require_relative 'entities/namespace_builder'
11
+ end
@@ -1,26 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.5.0
5
- class SmartCore::Container::Entity
4
+ # @since 0.7.0
5
+ class SmartCore::Container::Entities::Base
6
6
  # @return [String]
7
7
  #
8
8
  # @api private
9
- # @since 0.5.0
9
+ # @since 0.7.0
10
10
  attr_reader :external_name
11
11
 
12
12
  # @param external_name [String]
13
13
  # @return [void]
14
14
  #
15
15
  # @api private
16
- # @since 0.5.0
16
+ # @since 0.7.0
17
17
  def initialize(external_name)
18
18
  @external_name = external_name
19
19
  end
20
20
 
21
- # @return [void]
21
+ # @return [Any]
22
22
  #
23
23
  # @api private
24
- # @since 0.5.0
25
- def call; end
24
+ # @since 0.7.0
25
+ def resolve; end
26
26
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.7.0
5
+ class SmartCore::Container::Entities::Dependency < SmartCore::Container::Entities::Base
6
+ # @return [String]
7
+ #
8
+ # @api private
9
+ # @sicne 0.7.0
10
+ alias_method :dependency_name, :external_name
11
+
12
+ # @param dependency_name [String]
13
+ # @param dependency_definition [Proc]
14
+ # @return [void]
15
+ #
16
+ # @api private
17
+ # @since 0.7.0
18
+ def initialize(dependency_name, dependency_definition)
19
+ super(dependency_name)
20
+ @dependency_definition = dependency_definition
21
+ end
22
+
23
+ # @return [Any]
24
+ #
25
+ # @api private
26
+ # @since 0.7.0
27
+ def resolve
28
+ dependency_definition.call
29
+ end
30
+
31
+ private
32
+
33
+ # @return [Proc]
34
+ #
35
+ # @api private
36
+ # @since 0.7.0
37
+ attr_reader :dependency_definition
38
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.7.0
5
+ class SmartCore::Container::Entities::DependencyBuilder
6
+ class << self
7
+ # @param dependency_name [String]
8
+ # @param dependency_definition [Proc]
9
+ # @return [SmartCore::Container::Entities::Dependency]
10
+ #
11
+ # @api private
12
+ # @since 0.7.0
13
+ def build(dependency_name, dependency_definition)
14
+ new(dependency_name, dependency_definition).build
15
+ end
16
+ end
17
+
18
+ # @param dependency_name [String]
19
+ # @param dependency_definition [Proc]
20
+ # @return [void]
21
+ #
22
+ # @api private
23
+ # @since 0.7.0
24
+ def initialize(dependency_name, dependency_definition)
25
+ @dependency_name = dependency_name
26
+ @dependency_definition = dependency_definition
27
+ end
28
+
29
+ # @return [SmartCore::Container::Entities::Dependency]
30
+ #
31
+ # @api private
32
+ # @since 0.7.0
33
+ def build
34
+ SmartCore::Container::Entities::Dependency.new(dependency_name, dependency_definition)
35
+ end
36
+
37
+ private
38
+
39
+ # @return [String]
40
+ #
41
+ # @api private
42
+ # @since 0.7.0
43
+ attr_reader :dependency_name
44
+
45
+ # @return [Proc]
46
+ #
47
+ # @api private
48
+ # @since 0.7.0
49
+ attr_reader :dependency_definition
50
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.7.0
5
+ class SmartCore::Container::Entities::Namespace < SmartCore::Container::Entities::Base
6
+ # @return [String]
7
+ #
8
+ # @api private
9
+ # @since 0.7.0
10
+ alias_method :namespace_name, :external_name
11
+
12
+ # @param namespace_name [String]
13
+ # @return [void]
14
+ #
15
+ # @api private
16
+ # @since 0.7.0
17
+ def initialize(namespace_name)
18
+ super(namespace_name)
19
+ @container_klass = Class.new(SmartCore::Container)
20
+ @container_instance = nil
21
+ @lock = SmartCore::Container::ArbitaryLock.new
22
+ end
23
+
24
+ # @return [SmartCore::Container]
25
+ #
26
+ # @api private
27
+ # @since 0.7.0
28
+ def resolve
29
+ thread_safe { container_instance }
30
+ end
31
+
32
+ # @param dependencies_definition [Proc]
33
+ # @return [void]
34
+ #
35
+ # @api private
36
+ # @since 0.7.0
37
+ def append_definitions(dependencies_definition)
38
+ thread_safe { container_klass.instance_eval(&dependencies_definition) }
39
+ end
40
+
41
+ # @return [void]
42
+ #
43
+ # @api private
44
+ # @since 0.7.0
45
+ def freeze!
46
+ thread_safe { container_instance.freeze! }
47
+ end
48
+
49
+ private
50
+
51
+ # @return [Class<SmartCore::Container>]
52
+ #
53
+ # @api private
54
+ # @since 0.7.0
55
+ attr_reader :container_klass
56
+
57
+ # @return [SmartCore::Container]
58
+ #
59
+ # @api private
60
+ # @since 0.7.0
61
+ def container_instance
62
+ @container_instance ||= container_klass.new
63
+ end
64
+
65
+ # @param block [Block]
66
+ # @return [Any]
67
+ #
68
+ # @api private
69
+ # @since 0.7.0
70
+ def thread_safe(&block)
71
+ @lock.thread_safe(&block)
72
+ end
73
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.7.0
5
+ class SmartCore::Container::Entities::NamespaceBuilder
6
+ class << self
7
+ # @param namespace_name [String]
8
+ # @return [SmartCore::Container::Entities::Namespace]
9
+ #
10
+ # @api private
11
+ # @since 0.7.0
12
+ def build(namespace_name)
13
+ new(namespace_name).build
14
+ end
15
+ end
16
+
17
+ # @param namespace_name [String]
18
+ # @return [void]
19
+ #
20
+ # @api private
21
+ # @since 0.7.0
22
+ def initialize(namespace_name)
23
+ @namespace_name = namespace_name
24
+ end
25
+
26
+ # @return [SmartCore::Container::Entities::Namespace]
27
+ #
28
+ # @api private
29
+ # @since 0.7.0
30
+ def build
31
+ SmartCore::Container::Entities::Namespace.new(namespace_name)
32
+ end
33
+
34
+ private
35
+
36
+ # @return [String]
37
+ #
38
+ # @api private
39
+ # @since 0.7.0
40
+ attr_reader :namespace_name
41
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SmartCore::Container
4
+ # @api public
5
+ # @since 0.7.0
6
+ Error = Class.new(SmartCore::Error)
7
+
8
+ # @api public
9
+ # @since 0.7.0
10
+ ArgumentError = Class.new(SmartCore::ArgumentError)
11
+
12
+ # @api public
13
+ # @since 0.7.0
14
+ IncompatibleEntityNameError = Class.new(ArgumentError)
15
+
16
+ # @see SmartCore::Container::Registry
17
+ #
18
+ # @api public
19
+ # @since 0.7.0
20
+ FrozenRegistryError = Class.new(SmartCore::FrozenError)
21
+
22
+ # @see SmartCore::Container::Registry
23
+ #
24
+ # @api public
25
+ # @since 0.7.0
26
+ NonexistentEntityError = Class.new(Error)
27
+
28
+ # @see SmartCore::Container::DependencyCompatability::General
29
+ # @see SmartCore::Container::DependencyCompatability::Definition
30
+ # @see SmartCore::Container::DependencyCompatability::Registry
31
+ #
32
+ # @api public
33
+ # @since 0.7.0
34
+ DependencyOverNamespaceOverlapError = Class.new(Error)
35
+
36
+ # @see SmartCore::Container::DependencyCompatability::General
37
+ # @see SmartCore::Container::DependencyCompatability::Definition
38
+ # @see SmartCore::Container::DependencyCompatability::Registry
39
+ #
40
+ # @api public
41
+ # @since 0.7.0
42
+ NamespaceOverDependencyOverlapError = Class.new(Error)
43
+ end
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api priavate
4
- # @since 0.5.0
4
+ # @since 0.7.0
5
5
  module SmartCore::Container::KeyGuard
6
6
  class << self
7
7
  # @param key [Symbol, String]
8
8
  # @return [void]
9
9
  #
10
- # @raise [SmartCore::Container::ArgumentError]
10
+ # @raise [SmartCore::Container::IncompatibleEntityNameError]
11
11
  #
12
12
  # @api private
13
- # @since 0.5.0
13
+ # @since 0.7.0
14
14
  def prevent_incomparabilities!(key)
15
15
  raise(
16
- SmartCore::Container::ArgumentError,
16
+ SmartCore::Container::IncompatibleEntityNameError,
17
17
  'Namespace/Dependency name should be a symbol or a string'
18
18
  ) unless key.is_a?(String) || key.is_a?(Symbol)
19
19
  end
@@ -22,7 +22,7 @@ module SmartCore::Container::KeyGuard
22
22
  # @return [String]
23
23
  #
24
24
  # @api private
25
- # @since 0.5.0
25
+ # @since 0.7.0
26
26
  def indifferently_accessable_key(key)
27
27
  prevent_incomparabilities!(key)
28
28
  key.to_s
@@ -1,18 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api public
4
- # @since 0.5.0
4
+ # @since 0.7.0
5
5
  module SmartCore::Container::Mixin
6
6
  class << self
7
7
  # @param base_klass [Class]
8
8
  # @return [void]
9
9
  #
10
10
  # @api private
11
- # @since 0.5.0
11
+ # @since 0.7.0
12
12
  def included(base_klass)
13
13
  # rubocop:disable Metrics/LineLength
14
- base_klass.instance_variable_set(:@__smart_core_container_access_lock__, Mutex.new)
15
- base_klass.instance_variable_set(:@__smart_core_container_definition_lock__, Mutex.new)
14
+ base_klass.instance_variable_set(:@__smart_core_container_access_lock__, SmartCore::Container::ArbitaryLock.new)
16
15
  base_klass.instance_variable_set(:@__smart_core_container_klass__, Class.new(SmartCore::Container))
17
16
  base_klass.instance_variable_set(:@__smart_core_container__, nil)
18
17
  # rubocop:enable Metrics/LineLength
@@ -24,57 +23,62 @@ module SmartCore::Container::Mixin
24
23
  end
25
24
 
26
25
  # @api private
27
- # @since 0.5.0
26
+ # @since 0.7.0
28
27
  module ClassInheritance
29
28
  # @param child_klass [CLass]
30
29
  # @return [void]
31
30
  #
32
31
  # @api private
33
- # @since 0.5.0
32
+ # @since 0.7.0
34
33
  def inherited(child_klass)
35
34
  inherited_container_klass = Class.new(@__smart_core_container_klass__)
36
35
 
37
- child_klass.instance_variable_set(:@__smart_core_container_access_lock__, Mutex.new)
38
- child_klass.instance_variable_set(:@__smart_core_container_definition_lock__, Mutex.new)
36
+ # rubocop:disable Metrics/LineLength
37
+ child_klass.instance_variable_set(:@__smart_core_container_access_lock__, SmartCore::Container::ArbitaryLock.new)
39
38
  child_klass.instance_variable_set(:@__smart_core_container_klass__, inherited_container_klass)
40
39
  child_klass.instance_variable_set(:@__smart_core_container__, nil)
40
+ # rubocop:disable Metrics/LineLength
41
41
 
42
42
  super
43
43
  end
44
44
  end
45
45
 
46
46
  # @api private
47
- # @since 0.5.0
47
+ # @since 0.7.0
48
48
  module ClassMethods
49
+ # @param freeze_state [Boolean]
49
50
  # @param block [Proc]
50
51
  # @return [void]
51
52
  #
52
53
  # @api public
53
- # @since 0.5.0
54
- def dependencies(&block)
55
- @__smart_core_container_definition_lock__.synchronize do
54
+ # @since 0.7.0
55
+ def dependencies(freeze_state: false, &block)
56
+ @__smart_core_container_access_lock__.thread_safe do
56
57
  @__smart_core_container_klass__.instance_eval(&block) if block_given?
58
+ @__smart_core_container_klass__.instance_eval do
59
+ freeze_state!
60
+ end if freeze_state
57
61
  end
58
62
  end
59
63
 
60
64
  # @return [SmartCore::Container]
61
65
  #
62
66
  # @api public
63
- # @since 0.5.0
67
+ # @since 0.7.0
64
68
  def container
65
- @__smart_core_container_definition_lock__.synchronize do
69
+ @__smart_core_container_access_lock__.thread_safe do
66
70
  @__smart_core_container__ ||= @__smart_core_container_klass__.new
67
71
  end
68
72
  end
69
73
  end
70
74
 
71
75
  # @api private
72
- # @since 0.5.0
76
+ # @since 0.7.0
73
77
  module InstanceMethods
74
78
  # @return [SmartCore::Container]
75
79
  #
76
80
  # @api public
77
- # @since 0.5.0
81
+ # @since 0.7.0
78
82
  def container
79
83
  self.class.container
80
84
  end