mime_actor 0.6.1.rc1 → 0.6.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21ee0c18bb4a165c41bc6f583407eed1c79290dd4e63d99be14165b233b43104
4
- data.tar.gz: 9f590546538dacb9f4179168c6e9180fbb012efae5ba7b9c4ba33117316d70bf
3
+ metadata.gz: a448d97c462d23aa41abbbad40c1e2ba0a6336c0069e12dd905b18c7cfeee435
4
+ data.tar.gz: 3e7ee33e33138d37ef29ac4fa30d6b8284ca3fcb69dfd187b599be6a556aa963
5
5
  SHA512:
6
- metadata.gz: dab37a418fb045fe18c19a5c851706eefe558eebf1d8c247703c5248a2f355765981f9ec29c7053ba40b2b3799551340c0dad6c33048c64fca1b947337442346
7
- data.tar.gz: 919de90346b9cea32d464aade78ab6aaaa1af5ab87dd473e1347b32595cf1756cae9f1ceaed37278a8deb3f7fe215fd67076b9c3627535c31ba4a1672a5dcd99
6
+ metadata.gz: d1284b778dc593f3a674a8c8de22d9b10d15eb46fa1e47025c091a0103701eb38426e2fdc0951960cfcac02de8587e9d63b9fde5267a44cebf3606cd4d58bb44
7
+ data.tar.gz: 65f832e20fc1eeb9a2b6da8e37eb49041697afd66695a91998c65fd16942c915e2c2d4adb870d094858cc7fcb7dbd7849f25d229686849c57e8c98ef0904abcd
@@ -46,7 +46,6 @@ module MimeActor
46
46
  # end
47
47
  #
48
48
  def start_scene(action)
49
- action = action&.to_sym
50
49
  formats = acting_scenes.fetch(action, {})
51
50
 
52
51
  if formats.empty?
@@ -56,9 +55,7 @@ module MimeActor
56
55
 
57
56
  respond_to do |collector|
58
57
  formats.each do |format, actor|
59
- dispatch = self.class.dispatch_act(action: action, format: format, context: self) do
60
- cue_actor(actor.presence || "#{action}_#{format}")
61
- end
58
+ dispatch = -> { cue_actor(actor.presence || "#{action}_#{format}", action:, format:) }
62
59
  collector.public_send(format, &dispatch)
63
60
  end
64
61
  end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ module MimeActor
6
+ module Dispatcher
7
+ class MethodCall
8
+ attr_reader :method_name, :args
9
+
10
+ def initialize(method_name, *args)
11
+ @method_name = method_name
12
+ @args = args
13
+ validate!
14
+ end
15
+
16
+ def to_callable
17
+ lambda do |target|
18
+ throw :abort, method_name unless target.respond_to?(method_name)
19
+ method_call = target.method(method_name)
20
+ filtered_args = method_call.arity.negative? ? args : args.take(method_call.arity)
21
+ method_call.call(*filtered_args)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def validate!
28
+ raise ArgumentError, "invalid method name: #{method_name.inspect}" unless method_name in String | Symbol
29
+ end
30
+ end
31
+
32
+ class InstanceExec
33
+ attr_reader :block, :args
34
+
35
+ def initialize(block, *args)
36
+ @block = block
37
+ @args = args
38
+ validate!
39
+ end
40
+
41
+ def to_callable
42
+ lambda do |target|
43
+ filtered_args = block.arity.negative? ? args : args.take(block.arity)
44
+ target.instance_exec(*filtered_args, &block)
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def validate!
51
+ raise ArgumentError, "invalid block: #{block.inspect}" unless block in Proc
52
+ end
53
+ end
54
+
55
+ def self.build(callable, *args)
56
+ case callable
57
+ when String, Symbol
58
+ MethodCall.new(callable, *args)
59
+ when Proc
60
+ InstanceExec.new(callable, *args)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -2,8 +2,9 @@
2
2
 
3
3
  # :markup: markdown
4
4
 
5
- require "mime_actor/stage"
5
+ require "mime_actor/dispatcher"
6
6
  require "mime_actor/validator"
7
+ require "mime_actor/stage"
7
8
 
8
9
  require "active_support/concern"
9
10
  require "active_support/core_ext/array/wrap"
@@ -139,5 +140,59 @@ module MimeActor
139
140
  end
140
141
  end
141
142
  end
143
+
144
+ # Resolve the error provided with the registered handlers.
145
+ #
146
+ # The handled error will be returned to indicate successful handling.
147
+ #
148
+ # @param error the error instance to rescue
149
+ # @param action the `action` filter
150
+ # @param format the `format` filter
151
+ # @param visited the errors to skip after no rescue handler matched the filter
152
+ #
153
+ def rescue_actor(error, action:, format:, visited: [])
154
+ return if visited.include?(error)
155
+
156
+ visited << error
157
+ rescuer = find_rescuer(error, format:, action:)
158
+ if (dispatch = MimeActor::Dispatcher.build(rescuer, error, format, action))
159
+ dispatched = false
160
+ result = catch(:abort) do
161
+ dispatch.to_callable.call(self).tap { dispatched = true }
162
+ end
163
+ logger.error { "rescue error, cause: #{result.inspect}" } unless dispatched
164
+ error
165
+ elsif error&.cause
166
+ rescue_actor(error.cause, format:, action:, visited:)
167
+ end
168
+ end
169
+
170
+ private
171
+
172
+ def find_rescuer(error, format:, action:)
173
+ return unless error
174
+
175
+ *_, rescuer = actor_rescuers.reverse_each.detect do |rescuee, format_filter, action_filter|
176
+ next if action_filter.present? && !Array.wrap(action_filter).include?(action)
177
+ next if format_filter.present? && !Array.wrap(format_filter).include?(format)
178
+ next unless (klazz = constantize_rescuee(rescuee))
179
+
180
+ error.is_a?(klazz)
181
+ end
182
+ rescuer
183
+ end
184
+
185
+ def constantize_rescuee(class_or_name)
186
+ case class_or_name
187
+ when String, Symbol
188
+ begin
189
+ const_get(class_or_name)
190
+ rescue NameError
191
+ class_or_name.safe_constantize
192
+ end
193
+ else
194
+ class_or_name
195
+ end
196
+ end
142
197
  end
143
198
  end
@@ -3,6 +3,7 @@
3
3
  # :markup: markdown
4
4
 
5
5
  require "mime_actor/errors"
6
+ require "mime_actor/dispatcher"
6
7
  require "mime_actor/logging"
7
8
 
8
9
  require "active_support/concern"
@@ -19,7 +20,7 @@ module MimeActor
19
20
  include Logging
20
21
 
21
22
  included do
22
- mattr_accessor :raise_on_missing_actor, instance_writer: false, default: false
23
+ mattr_accessor :raise_on_actor_error, instance_writer: false, default: false
23
24
  end
24
25
 
25
26
  module ClassMethods
@@ -71,17 +72,14 @@ module MimeActor
71
72
  #
72
73
  # NOTE: method call on actor if it is String or Symbol. Proc#call if actor is Proc
73
74
  #
74
- # @param actor either a method name or a block to evaluate
75
- def cue_actor(actor, *args)
76
- result = case actor
77
- when String, Symbol
78
- actor_method_call(actor, *args)
79
- when Proc
80
- actor_proc_call(actor, *args)
81
- else
82
- raise TypeError, "invalid actor, got: #{actor.inspect}"
83
- end
75
+ # @param actor either a method name or a Proc to evaluate
76
+ # @param args arguments to be passed when calling the actor
77
+ #
78
+ def cue_actor(actor, *args, action:, format:)
79
+ dispatch = MimeActor::Dispatcher.build(actor, *args)
80
+ raise TypeError, "invalid actor, got: #{actor.inspect}" unless dispatch
84
81
 
82
+ result = dispatch_actor(dispatch, action:, format:)
85
83
  if block_given?
86
84
  yield result
87
85
  else
@@ -91,20 +89,24 @@ module MimeActor
91
89
 
92
90
  private
93
91
 
94
- def actor_method_call(actor_method, *args)
95
- unless self.class.actor?(actor_method)
96
- raise MimeActor::ActorNotFound, actor_method if raise_on_missing_actor
97
-
98
- logger.warn { "actor #{actor_method.inspect} not found" }
99
- return
92
+ def dispatch_actor(dispatch, action:, format:)
93
+ dispatched = false
94
+ rescued = false
95
+ result = catch(:abort) do
96
+ dispatch.to_callable.call(self).tap { dispatched = true }
97
+ rescue StandardError => e
98
+ rescued = respond_to?(:rescue_actor) && rescue_actor(e, action:, format:)
99
+ raise unless rescued
100
100
  end
101
-
102
- public_send(actor_method, *args)
101
+ handle_actor_error(result) unless dispatched || rescued
102
+ result if dispatched
103
103
  end
104
104
 
105
- def actor_proc_call(actor_proc, *args)
106
- passable_args = actor_proc.arity.negative? ? args : args.take(actor_proc.arity)
107
- instance_exec(*passable_args, &actor_proc)
105
+ def handle_actor_error(actor)
106
+ error = MimeActor::ActorNotFound.new(actor)
107
+ raise error if raise_on_actor_error
108
+
109
+ logger.error { "actor error, cause: #{error.inspect}" }
108
110
  end
109
111
  end
110
112
  end
@@ -4,18 +4,18 @@
4
4
 
5
5
  module MimeActor
6
6
  def self.version
7
- gem_version
7
+ VERSION::STRING
8
8
  end
9
9
 
10
10
  def self.gem_version
11
- Gem::Version.new VERSION::STRING
11
+ Gem::Version.new(VERSION::STRING)
12
12
  end
13
13
 
14
14
  module VERSION
15
15
  MAJOR = 0
16
16
  MINOR = 6
17
- BUILD = 1
18
- PRE = "rc1"
17
+ BUILD = 2
18
+ PRE = nil
19
19
 
20
20
  STRING = [MAJOR, MINOR, BUILD, PRE].compact.join(".")
21
21
  end
data/lib/mime_actor.rb CHANGED
@@ -7,6 +7,7 @@ require "mime_actor/version"
7
7
  require "mime_actor/errors"
8
8
 
9
9
  require "active_support/dependencies/autoload"
10
+ require "active_support/deprecation"
10
11
 
11
12
  module MimeActor
12
13
  extend ActiveSupport::Autoload
@@ -17,4 +18,18 @@ module MimeActor
17
18
  autoload :Rescue
18
19
  autoload :Validator
19
20
  autoload :Logging
21
+
22
+ def self.deprecator
23
+ @deprecator ||= ActiveSupport::Deprecation.new("0.7.0", "MimeActor")
24
+ end
25
+
26
+ [
27
+ [MimeActor::Rescue::ClassMethods, { rescue_actor: "use #rescue_actor instance method" }],
28
+ [MimeActor::Scene::ClassMethods, { act_on_format: :respond_act_to }],
29
+ [MimeActor::Stage::ClassMethods, { actor?: "no longer supported, use Object#respond_to?" }],
30
+ [MimeActor::Stage::ClassMethods, { dispatch_cue: "no longer support anonymous proc with rescue" }],
31
+ [MimeActor::Stage::ClassMethods, { dispatch_act: "no longer support anonymous proc with rescue" }]
32
+ ].each do |klazz, *args|
33
+ deprecator.deprecate_methods(klazz, *args)
34
+ end
20
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mime_actor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1.rc1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Chang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-13 00:00:00.000000000 Z
11
+ date: 2024-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -71,6 +71,7 @@ files:
71
71
  - codecov.yml
72
72
  - lib/mime_actor.rb
73
73
  - lib/mime_actor/action.rb
74
+ - lib/mime_actor/dispatcher.rb
74
75
  - lib/mime_actor/errors.rb
75
76
  - lib/mime_actor/logging.rb
76
77
  - lib/mime_actor/rescue.rb