convenient_service 0.18.0 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -3
  3. data/lib/convenient_service/commands/is_service.rb +28 -0
  4. data/lib/convenient_service/commands/is_service_class.rb +30 -0
  5. data/lib/convenient_service/commands.rb +4 -0
  6. data/lib/convenient_service/common/plugins.rb +2 -3
  7. data/lib/convenient_service/core/concern/class_methods.rb +3 -0
  8. data/lib/convenient_service/core/entities/config/entities/concerns/entities/stack.rb +22 -0
  9. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/container/concern/instance_methods.rb +1 -1
  10. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middleware_creators/observable/entities/event.rb +13 -15
  11. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middlewares/chain/commands/normalize_env.rb +55 -0
  12. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middlewares/chain/commands.rb +1 -0
  13. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middlewares/chain/concern/instance_methods.rb +3 -3
  14. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middlewares/classic.rb +14 -0
  15. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/stack.rb +22 -0
  16. data/lib/convenient_service/dependencies/built_in.rb +0 -7
  17. data/lib/convenient_service/dependencies/extractions/ds.rb +45 -0
  18. data/lib/convenient_service/dependencies/only_queries.rb +29 -0
  19. data/lib/convenient_service/dependencies/queries/gems/active_model.rb +38 -0
  20. data/lib/convenient_service/dependencies/queries/gems/logger.rb +39 -0
  21. data/lib/convenient_service/dependencies/queries/gems/paint.rb +39 -0
  22. data/lib/convenient_service/dependencies/queries/gems/rspec.rb +60 -0
  23. data/lib/convenient_service/dependencies/queries/ruby.rb +103 -0
  24. data/lib/convenient_service/dependencies/queries/version/null_version.rb +87 -0
  25. data/lib/convenient_service/dependencies/queries/version.rb +87 -0
  26. data/lib/convenient_service/dependencies/queries.rb +536 -0
  27. data/lib/convenient_service/dependencies.rb +2 -438
  28. data/lib/convenient_service/feature/configs/standard.rb +0 -2
  29. data/lib/convenient_service/service/configs/amazing_print_inspect/aliases.rb +7 -0
  30. data/lib/convenient_service/service/configs/amazing_print_inspect.rb +61 -0
  31. data/lib/convenient_service/service/configs/awesome_print_inspect.rb +1 -1
  32. data/lib/convenient_service/service/configs/{minimal.rb → essential.rb} +2 -107
  33. data/lib/convenient_service/service/configs/standard/v1.rb +5 -10
  34. data/lib/convenient_service/service/configs/standard.rb +19 -31
  35. data/lib/convenient_service/service/configs.rb +1 -1
  36. data/lib/convenient_service/service/plugins/can_have_connected_steps/entities/expressions/and.rb +4 -1
  37. data/lib/convenient_service/service/plugins/can_have_connected_steps/entities/expressions/empty.rb +4 -4
  38. data/lib/convenient_service/service/plugins/can_have_connected_steps/entities/step_collection.rb +7 -0
  39. data/lib/convenient_service/service/plugins/can_have_fallbacks/concern.rb +18 -0
  40. data/lib/convenient_service/service/plugins/can_have_fallbacks/exceptions.rb +22 -4
  41. data/lib/convenient_service/service/plugins/can_have_fallbacks/middleware.rb +3 -3
  42. data/lib/convenient_service/service/plugins/can_have_rollbacks/middleware.rb +66 -0
  43. data/lib/convenient_service/service/plugins/can_have_rollbacks.rb +3 -0
  44. data/lib/convenient_service/service/plugins/can_have_sequential_steps/entities/step_collection.rb +7 -0
  45. data/lib/convenient_service/service/plugins/can_have_steps/commands/is_step.rb +34 -0
  46. data/lib/convenient_service/service/plugins/can_have_steps/commands.rb +1 -0
  47. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/concern/instance_methods.rb +22 -14
  48. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_be_method_step/can_be_executed/middleware.rb +1 -15
  49. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_have_fallbacks/exceptions.rb +53 -0
  50. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_have_fallbacks/middleware.rb +60 -15
  51. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_have_fallbacks.rb +1 -0
  52. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/has_amazing_print_inspect/concern.rb +46 -0
  53. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/has_amazing_print_inspect.rb +3 -0
  54. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/has_awesome_print_inspect/concern.rb +3 -2
  55. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/has_result/middleware.rb +26 -1
  56. data/lib/convenient_service/service/plugins/can_have_steps.rb +41 -0
  57. data/lib/convenient_service/service/plugins/can_have_stubbed_results/commands/fetch_all_services_stubbed_results_cache.rb +2 -2
  58. data/lib/convenient_service/service/plugins/forbids_convenient_service_entities_as_constructor_arguments/exceptions.rb +53 -0
  59. data/lib/convenient_service/service/plugins/forbids_convenient_service_entities_as_constructor_arguments/middleware.rb +108 -0
  60. data/lib/convenient_service/service/plugins/forbids_convenient_service_entities_as_constructor_arguments.rb +4 -0
  61. data/lib/convenient_service/service/plugins/has_amazing_print_inspect/concern.rb +39 -0
  62. data/lib/convenient_service/service/plugins/has_amazing_print_inspect.rb +3 -0
  63. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/can_be_from_exception/concern.rb +32 -0
  64. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/can_be_from_exception.rb +3 -0
  65. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/can_have_step/concern.rb +7 -0
  66. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_amazing_print_inspect/concern.rb +41 -0
  67. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_amazing_print_inspect.rb +3 -0
  68. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_awesome_print_inspect/concern.rb +2 -2
  69. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/concern/instance_methods.rb +0 -140
  70. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/code/plugins/has_amazing_print_inspect/concern.rb +46 -0
  71. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/code/plugins/has_amazing_print_inspect.rb +3 -0
  72. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/data/plugins/has_amazing_print_inspect/concern.rb +46 -0
  73. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/data/plugins/has_amazing_print_inspect.rb +3 -0
  74. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/message/plugins/has_amazing_print_inspect/concern.rb +46 -0
  75. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/message/plugins/has_amazing_print_inspect.rb +3 -0
  76. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/status/plugins/has_amazing_print_inspect/concern.rb +46 -0
  77. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/status/plugins/has_amazing_print_inspect.rb +3 -0
  78. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/helps_to_learn_similarities_with_common_objects/concern/instance_methods.rb +161 -0
  79. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/helps_to_learn_similarities_with_common_objects/concern.rb +27 -0
  80. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/helps_to_learn_similarities_with_common_objects/exceptions.rb +34 -0
  81. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/helps_to_learn_similarities_with_common_objects.rb +4 -0
  82. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins.rb +2 -0
  83. data/lib/convenient_service/service/plugins/has_mermaid_flowchart/concern.rb +6 -1
  84. data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/middleware.rb +1 -0
  85. data/lib/convenient_service/service/plugins.rb +3 -1
  86. data/lib/convenient_service/support/counter.rb +2 -0
  87. data/lib/convenient_service/support/middleware/stack_builder.rb +37 -0
  88. data/lib/convenient_service/support/thread_safe_counter.rb +1 -0
  89. data/lib/convenient_service/support.rb +0 -3
  90. data/lib/convenient_service/utils/object/get_own_method.rb +54 -0
  91. data/lib/convenient_service/utils/object/safe_send.rb +84 -0
  92. data/lib/convenient_service/utils/object.rb +24 -0
  93. data/lib/convenient_service/utils/string/enclose.rb +52 -0
  94. data/lib/convenient_service/utils/string.rb +5 -0
  95. data/lib/convenient_service/version.rb +1 -1
  96. data/lib/convenient_service.rb +62 -0
  97. metadata +149 -16
  98. data/lib/convenient_service/common/plugins/normalizes_env/middleware.rb +0 -31
  99. data/lib/convenient_service/common/plugins/normalizes_env.rb +0 -3
  100. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_have_fallbacks/result.rb +0 -3
  101. data/lib/convenient_service/services.rb +0 -4
  102. data/lib/convenient_service/support/gems/active_model.rb +0 -36
  103. data/lib/convenient_service/support/gems/logger.rb +0 -37
  104. data/lib/convenient_service/support/gems/paint.rb +0 -37
  105. data/lib/convenient_service/support/gems/rspec.rb +0 -58
  106. data/lib/convenient_service/support/ruby.rb +0 -53
  107. data/lib/convenient_service/support/version/null_version.rb +0 -85
  108. data/lib/convenient_service/support/version.rb +0 -75
  109. /data/lib/convenient_service/{support → dependencies/queries}/gems.rb +0 -0
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Service
5
+ module Plugins
6
+ module HasJSendResult
7
+ module Entities
8
+ class Result
9
+ module Plugins
10
+ module HelpsToLearnSimilaritiesWithCommonObjects
11
+ module Exceptions
12
+ class ErrorHasNoOtherTypeRepresentation < ::ConvenientService::Exception
13
+ ##
14
+ # @return [void]
15
+ #
16
+ def initialize_with_kwargs(type:)
17
+ message = <<~TEXT
18
+ Error results have no `#{type}` representation.
19
+
20
+ They are semantically similar to exceptions.
21
+ TEXT
22
+
23
+ initialize(message)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helps_to_learn_similarities_with_common_objects/concern"
4
+ require_relative "helps_to_learn_similarities_with_common_objects/exceptions"
@@ -2,12 +2,14 @@
2
2
 
3
3
  require_relative "plugins/can_recalculate_result"
4
4
  require_relative "plugins/has_negated_result"
5
+ require_relative "plugins/can_be_from_exception"
5
6
  require_relative "plugins/can_be_own_result"
6
7
  require_relative "plugins/can_be_stubbed_result"
7
8
  require_relative "plugins/can_have_fallbacks"
8
9
  require_relative "plugins/has_j_send_status_and_attributes"
9
10
  require_relative "plugins/has_inspect"
10
11
  require_relative "plugins/has_stubbed_result_invocations_counter"
12
+ require_relative "plugins/helps_to_learn_similarities_with_common_objects"
11
13
  require_relative "plugins/can_have_step"
12
14
  require_relative "plugins/can_have_parent_result"
13
15
  require_relative "plugins/can_have_checked_status"
@@ -3,13 +3,18 @@
3
3
  module ConvenientService
4
4
  module Service
5
5
  module Plugins
6
+ ##
7
+ # @api private
8
+ #
9
+ # @note `HasMermaidFlowchart` is experimental. It is NOT decided yet whether its support will be continued. For example, it does NOT work with `or_step`.
10
+ #
6
11
  module HasMermaidFlowchart
7
12
  module Concern
8
13
  include Support::Concern
9
14
 
10
15
  class_methods do
11
16
  ##
12
- # @api public
17
+ # @api private
13
18
  #
14
19
  # @return [ConvenientService::Service::Plugins::HasMermaidFlowchart::Entities::Flowchart]
15
20
  #
@@ -74,6 +74,7 @@ module ConvenientService
74
74
  data: {exception: exception},
75
75
  message: format_exception(exception, *args, **kwargs, &block)
76
76
  )
77
+ .copy(overrides: {kwargs: {from_exception: true}})
77
78
  end
78
79
 
79
80
  ##
@@ -2,7 +2,7 @@
2
2
 
3
3
  ##
4
4
  # @internal
5
- # NOTE: Order matters.
5
+ # NOTE: Some plugins are order-dependent.
6
6
  #
7
7
  require_relative "plugins/has_result"
8
8
  require_relative "plugins/has_negated_result"
@@ -18,8 +18,10 @@ require_relative "plugins/can_recalculate_result"
18
18
  require_relative "plugins/can_have_method_steps"
19
19
  require_relative "plugins/can_have_stubbed_results"
20
20
  require_relative "plugins/can_have_fallbacks"
21
+ require_relative "plugins/can_have_rollbacks"
21
22
  require_relative "plugins/collects_services_in_exception"
22
23
  require_relative "plugins/counts_stubbed_results_invocations"
24
+ require_relative "plugins/forbids_convenient_service_entities_as_constructor_arguments"
23
25
  require_relative "plugins/has_inspect"
24
26
  require_relative "plugins/has_j_send_result_short_syntax"
25
27
  require_relative "plugins/has_j_send_result_status_check_short_syntax"
@@ -200,6 +200,8 @@ module ConvenientService
200
200
  end
201
201
 
202
202
  ##
203
+ # @return [Integer]
204
+ #
203
205
  # @internal
204
206
  # NOTE: Instance variables are accessed directly to release the lock faster.
205
207
  #
@@ -18,6 +18,9 @@ module ConvenientService
18
18
  #
19
19
  # @see https://github.com/marian13/ruby-middleware/blob/v0.4.2/lib/middleware/builder.rb#L43
20
20
  #
21
+ # @internal
22
+ # TODO: Direct specs.
23
+ #
21
24
  def initialize(opts = {}, &block)
22
25
  super
23
26
 
@@ -27,10 +30,41 @@ module ConvenientService
27
30
  self.stack = opts[:stack] if opts.has_key?(:stack)
28
31
  end
29
32
 
33
+ ##
34
+ # @param middleware [ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Middlewares::Base]
35
+ # @param args [Array<Object>]
36
+ # @param block [Proc, nil]
37
+ # @return [ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Stack]
38
+ #
39
+ # @internal
40
+ # TODO: Rewrite middleware backend. Consider to use `Array` descendant?
41
+ #
42
+ def unshift(middleware, *args, &block)
43
+ stack.unshift([middleware, args, block])
44
+
45
+ self
46
+ end
47
+
48
+ ##
49
+ # @return [ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Stack]
50
+ #
51
+ alias_method :prepend, :unshift
52
+
53
+ ##
54
+ # @return [ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Stack]
55
+ #
56
+ # @internal
57
+ # TODO: Direct specs.
58
+ #
59
+ alias_method :remove, :delete
60
+
30
61
  ##
31
62
  # @param other [ConvenientService::Support::Middleware::StackBuilder, Object]
32
63
  # @return [Boolean, nil]
33
64
  #
65
+ # @internal
66
+ # TODO: Direct specs.
67
+ #
34
68
  def ==(other)
35
69
  return unless other.instance_of?(self.class)
36
70
 
@@ -56,6 +90,9 @@ module ConvenientService
56
90
  ##
57
91
  # @return [ConvenientService::Support::Middleware::StackBuilder]
58
92
  #
93
+ # @internal
94
+ # TODO: Direct specs.
95
+ #
59
96
  def dup
60
97
  self.class.new(
61
98
  ##
@@ -2,6 +2,7 @@
2
2
 
3
3
  module ConvenientService
4
4
  module Support
5
+ ##
5
6
  # @internal
6
7
  # NOTE: Mutex and Semaphore docs.
7
8
  # - https://ruby-doc.org/core-2.7.0/Mutex.html
@@ -20,11 +20,8 @@ require_relative "support/counter"
20
20
  require_relative "support/delegate"
21
21
  require_relative "support/dependency_container"
22
22
  require_relative "support/finite_loop"
23
- require_relative "support/gems"
24
23
  require_relative "support/method_parameters"
25
24
  require_relative "support/middleware"
26
25
  require_relative "support/raw_value"
27
- require_relative "support/ruby"
28
26
  require_relative "support/safe_method"
29
27
  require_relative "support/thread_safe_counter"
30
- require_relative "support/version"
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Utils
5
+ module Object
6
+ class GetOwnMethod < Support::Command
7
+ ##
8
+ # @!attribute [r] object
9
+ # @return [Object] Can be any type.
10
+ #
11
+ attr_reader :object
12
+
13
+ ##
14
+ # @!attribute [r] method_name
15
+ # @return [Symbol, String]
16
+ #
17
+ attr_reader :method_name
18
+
19
+ ##
20
+ # @!attribute [r] private
21
+ # @return [Boolean]
22
+ #
23
+ attr_reader :private
24
+
25
+ ##
26
+ # @param object [Object] Can be any type.
27
+ # @param method_name [Symbol, String]
28
+ # @param private [Boolean]
29
+ #
30
+ def initialize(object, method_name, private: false)
31
+ @object = object
32
+ @method_name = method_name
33
+ @private = private
34
+ end
35
+
36
+ ##
37
+ # @return [Class]
38
+ #
39
+ # @internal
40
+ # NOTE: `own_method.bind(object).call` is logically the same as `own_method.bind_call(object)`.
41
+ # - https://ruby-doc.org/core-2.7.1/UnboundMethod.html#method-i-bind_call
42
+ # - https://blog.saeloun.com/2019/10/17/ruby-2-7-adds-unboundmethod-bind_call-method.html
43
+ #
44
+ def call
45
+ own_method = Utils::Module.get_own_instance_method(object.class, method_name, private: private)
46
+
47
+ return unless own_method
48
+
49
+ own_method.bind(object)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Utils
5
+ module Object
6
+ ##
7
+ # Returns `nil` when `object` does NOT respond to `method`.
8
+ # Otherwise it calls `method` on `object` and returns its value.
9
+ # If calling `method` on `object` raises an exception, it is rescued and `nil` is returned.
10
+ # Only `StandardError` exceptions are rescued.
11
+ # Uses `__send__` under the hood.
12
+ #
13
+ # @note `ArgumentError` is `StandardError` descendant, so it is also rescued. It is up to the client code to ensure that valid arguments are passed.
14
+ # @see https://ruby-doc.org/core-2.7.0/BasicObject.html#method-i-__send__
15
+ # @see https://ruby-doc.org/core-2.7.0/Object.html#method-i-respond_to-3F
16
+ # @see https://ruby-doc.org/core-2.7.0/StandardError.html
17
+ # @see https://ruby-doc.org/core-2.7.0/ArgumentError.html
18
+ #
19
+ class SafeSend < Support::Command
20
+ ##
21
+ # @!attribute [r] object
22
+ # @return [Object] Can be any type.
23
+ #
24
+ attr_reader :object
25
+
26
+ ##
27
+ # @!attribute [r] method
28
+ # @return [String, Symbol]
29
+ #
30
+ attr_reader :method
31
+
32
+ ##
33
+ # @!attribute [r] args
34
+ # @return [Array<Object>]
35
+ #
36
+ attr_reader :args
37
+
38
+ ##
39
+ # @!attribute [r] kwargs
40
+ # @return [Hash{Symbol => Object}]
41
+ #
42
+ attr_reader :kwargs
43
+
44
+ ##
45
+ # @!attribute [r] block
46
+ # @return [Proc, nil]
47
+ #
48
+ attr_reader :block
49
+
50
+ ##
51
+ # @param object [Object] Can be any type.
52
+ # @param method [String, Symbol]
53
+ # @param args [Array<Object>]
54
+ # @param kwargs [Hash{Symbol => Object}]
55
+ # @param block [Proc, nil]
56
+ #
57
+ def initialize(object, method, *args, **kwargs, &block)
58
+ @object = object
59
+ @method = method
60
+ @args = args
61
+ @kwargs = kwargs
62
+ @block = block
63
+ end
64
+
65
+ ##
66
+ # @return [Object] Can be any type.
67
+ #
68
+ # @internal
69
+ # NOTE: `true` in `respond_to?(method, true)` means to look for protected and private methods as well.
70
+ # - https://ruby-doc.org/core-2.7.0/Object.html#method-i-respond_to-3F
71
+ #
72
+ def call
73
+ return unless object.respond_to?(method, true)
74
+
75
+ begin
76
+ object.__send__(method, *args, **kwargs, &block)
77
+ rescue
78
+ nil
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -2,10 +2,12 @@
2
2
 
3
3
  require_relative "object/clamp_class"
4
4
  require_relative "object/duck_class"
5
+ require_relative "object/get_own_method"
5
6
  require_relative "object/instance_variable_delete"
6
7
  require_relative "object/instance_variable_fetch"
7
8
  require_relative "object/memoize_including_falsy_values"
8
9
  require_relative "object/resolve_type"
10
+ require_relative "object/safe_send"
9
11
 
10
12
  module ConvenientService
11
13
  module Utils
@@ -53,6 +55,20 @@ module ConvenientService
53
55
  MemoizeIncludingFalsyValues.call(...)
54
56
  end
55
57
 
58
+ ##
59
+ # @example
60
+ # object = Object.new.tap { |object| object.instance_eval { self.class.attr_reader :foo } }
61
+ #
62
+ # ConvenientService::Utils::Object.own_method(object, :foo)
63
+ # # => #<Method: #<Object:0x0000555e524252d8>.foo() ...>
64
+ #
65
+ # ConvenientService::Utils::Object.own_method(object, :puts)
66
+ # # => nil
67
+ #
68
+ def own_method(...)
69
+ GetOwnMethod.call(...)
70
+ end
71
+
56
72
  ##
57
73
  # @example
58
74
  # ConvenientService::Utils::Object.resolve_type("foo")
@@ -60,6 +76,14 @@ module ConvenientService
60
76
  def resolve_type(...)
61
77
  ResolveType.call(...)
62
78
  end
79
+
80
+ ##
81
+ # @example
82
+ # ConvenientService::Utils::Object.safe_send(object, method, *args, **kwargs, &block)
83
+ #
84
+ def safe_send(...)
85
+ SafeSend.call(...)
86
+ end
63
87
  end
64
88
  end
65
89
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # @example Common usage.
5
+ # ConvenientService::Utils::String::Enclose.call("foo", "_")
6
+ # # => "_foo_"
7
+ #
8
+ # ConvenientService::Utils::String::Enclose.call("", "_")
9
+ # # => "_"
10
+ #
11
+ # ConvenientService::Utils::String::Enclose.call(nil, "_")
12
+ # # => "_"
13
+ #
14
+ module ConvenientService
15
+ module Utils
16
+ module String
17
+ class Enclose < Support::Command
18
+ ##
19
+ # @!attribute [r] string
20
+ # @return [String]
21
+ #
22
+ attr_reader :string
23
+
24
+ ##
25
+ # @!attribute [r] char
26
+ # @return [String]
27
+ #
28
+ attr_reader :char
29
+
30
+ ##
31
+ # @param string [String]
32
+ # @param char [String]
33
+ # @return [void]
34
+ #
35
+ def initialize(string, char)
36
+ @string = string
37
+ @char = char
38
+ end
39
+
40
+ ##
41
+ # @return [String]
42
+ #
43
+ def call
44
+ return char unless string
45
+ return char if string.empty?
46
+
47
+ "#{char}#{string}#{char}"
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "string/camelize"
4
4
  require_relative "string/demodulize"
5
+ require_relative "string/enclose"
5
6
  require_relative "string/split"
6
7
  require_relative "string/truncate"
7
8
 
@@ -17,6 +18,10 @@ module ConvenientService
17
18
  Demodulize.call(...)
18
19
  end
19
20
 
21
+ def enclose(...)
22
+ Enclose.call(...)
23
+ end
24
+
20
25
  def split(...)
21
26
  Split.call(...)
22
27
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ConvenientService
4
- VERSION = "0.18.0"
4
+ VERSION = "0.19.0"
5
5
  end
@@ -35,6 +35,12 @@ require_relative "convenient_service/service"
35
35
  #
36
36
  require_relative "convenient_service/feature"
37
37
 
38
+ ##
39
+ # @internal
40
+ # Convenient Service Commands.
41
+ #
42
+ require_relative "convenient_service/commands"
43
+
38
44
  ##
39
45
  # @internal
40
46
  # Convenient Service Aliases.
@@ -52,6 +58,62 @@ module ConvenientService
52
58
  ::ENV["CONVENIENT_SERVICE_DEBUG"] == "true"
53
59
  end
54
60
 
61
+ ##
62
+ # Checks whether a class is a service class.
63
+ #
64
+ # @api public
65
+ #
66
+ # @param service_class [Object] Can be any type.
67
+ # @return [Boolean]
68
+ #
69
+ # @example Simple usage.
70
+ # class Service
71
+ # include ConvenientService::Standard::Config
72
+ #
73
+ # def result
74
+ # success
75
+ # end
76
+ # end
77
+ #
78
+ # ConvenientService.service_class?(Service)
79
+ # # => true
80
+ #
81
+ # ConvenientService.service_class?(42)
82
+ # # => false
83
+ #
84
+ def service_class?(service_class)
85
+ Commands::IsServiceClass[service_class: service_class]
86
+ end
87
+
88
+ ##
89
+ # Checks whether an object is a service instance.
90
+ #
91
+ # @api public
92
+ #
93
+ # @param service [Object] Can be any type.
94
+ # @return [Boolean]
95
+ #
96
+ # @example Simple usage.
97
+ # class Service
98
+ # include ConvenientService::Standard::Config
99
+ #
100
+ # def result
101
+ # success
102
+ # end
103
+ # end
104
+ #
105
+ # service = Service.new
106
+ #
107
+ # ConvenientService.service?(service)
108
+ # # => true
109
+ #
110
+ # ConvenientService.service?(42)
111
+ # # => false
112
+ #
113
+ def service?(service)
114
+ Commands::IsService[service: service]
115
+ end
116
+
55
117
  ##
56
118
  # @api public
57
119
  #