mime_actor 0.6.4 → 0.7.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/CHANGELOG.md +197 -0
- data/COMPARE.md +40 -32
- data/README.md +130 -25
- data/lib/mime_actor/action.rb +23 -15
- data/lib/mime_actor/callbacks.rb +101 -126
- data/lib/mime_actor/deprecator.rb +1 -11
- data/lib/mime_actor/errors.rb +2 -2
- data/lib/mime_actor/logging.rb +12 -2
- data/lib/mime_actor/railtie.rb +1 -1
- data/lib/mime_actor/rescue.rb +6 -74
- data/lib/mime_actor/scene.rb +77 -68
- data/lib/mime_actor/stage.rb +3 -47
- data/lib/mime_actor/validator.rb +4 -0
- data/lib/mime_actor/version.rb +2 -2
- metadata +13 -26
data/lib/mime_actor/callbacks.rb
CHANGED
@@ -5,18 +5,24 @@
|
|
5
5
|
require "mime_actor/validator"
|
6
6
|
|
7
7
|
require "active_support/callbacks"
|
8
|
+
require "active_support/code_generator"
|
8
9
|
require "active_support/concern"
|
9
|
-
require "active_support/core_ext/
|
10
|
-
require "active_support/core_ext/object/blank"
|
10
|
+
require "active_support/core_ext/module/attr_internal"
|
11
11
|
|
12
12
|
module MimeActor
|
13
13
|
# # MimeActor Callbacks
|
14
14
|
#
|
15
15
|
# MimeActor provides hooks during the life cycle of an act. Available callbacks are:
|
16
16
|
#
|
17
|
-
# -
|
18
|
-
# -
|
19
|
-
# -
|
17
|
+
# - append_act_before
|
18
|
+
# - append_act_around
|
19
|
+
# - append_act_after
|
20
|
+
# - act_before
|
21
|
+
# - act_around
|
22
|
+
# - act_after
|
23
|
+
# - prepend_act_before
|
24
|
+
# - prepend_act_around
|
25
|
+
# - prepend_act_after
|
20
26
|
#
|
21
27
|
# NOTE: Calling the same callback multiple times will overwrite previous callback definitions.
|
22
28
|
#
|
@@ -27,19 +33,25 @@ module MimeActor
|
|
27
33
|
include MimeActor::Validator
|
28
34
|
|
29
35
|
included do
|
36
|
+
attr_internal_reader :act_action, :act_format
|
30
37
|
define_callbacks :act, skip_after_callbacks_if_terminated: true
|
31
|
-
|
32
|
-
%i[before after around].each { |kind| define_act_callbacks(kind) }
|
38
|
+
generate_act_callback_methods
|
33
39
|
end
|
34
40
|
|
35
41
|
module ClassMethods
|
36
|
-
class
|
37
|
-
|
38
|
-
|
42
|
+
class ActMatcher
|
43
|
+
attr_reader :actions, :formats
|
44
|
+
|
45
|
+
def initialize(actions, formats)
|
46
|
+
@actions = actions&.then { |a| Array(a).to_set(&:to_sym) }
|
47
|
+
@formats = formats&.then { |f| Array(f).to_set(&:to_sym) }
|
39
48
|
end
|
40
49
|
|
41
50
|
def match?(controller)
|
42
|
-
|
51
|
+
matched = true
|
52
|
+
matched &= actions.include?(controller.act_action) if !actions.nil? && controller.respond_to?(:act_action)
|
53
|
+
matched &= formats.include?(controller.act_format) if !formats.nil? && controller.respond_to?(:act_format)
|
54
|
+
matched
|
43
55
|
end
|
44
56
|
|
45
57
|
alias after match?
|
@@ -47,154 +59,117 @@ module MimeActor
|
|
47
59
|
alias around match?
|
48
60
|
end
|
49
61
|
|
50
|
-
def callback_chain_name(format = nil)
|
51
|
-
if format.present?
|
52
|
-
validate!(:format, format)
|
53
|
-
:"act_#{format}"
|
54
|
-
else
|
55
|
-
:act
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def callback_chain_defined?(name)
|
60
|
-
!!get_callbacks(name)
|
61
|
-
end
|
62
|
-
|
63
62
|
private
|
64
63
|
|
65
|
-
def define_callback_chain(name)
|
66
|
-
return if callback_chain_defined?(name)
|
67
|
-
|
68
|
-
define_callbacks name, skip_after_callbacks_if_terminated: true
|
69
|
-
end
|
70
|
-
|
71
64
|
def configure_callbacks(callbacks, actions, formats, block)
|
72
65
|
options = {}
|
73
|
-
options[:if] =
|
66
|
+
options[:if] = ActMatcher.new(actions, formats) unless actions.nil? && formats.nil?
|
74
67
|
callbacks.push(block) if block
|
75
68
|
|
76
|
-
formats = Array.wrap(formats)
|
77
|
-
formats << nil if formats.empty?
|
78
|
-
|
79
69
|
callbacks.each do |callback|
|
80
|
-
|
81
|
-
chain = callback_chain_name(format)
|
82
|
-
define_callback_chain(chain)
|
83
|
-
yield chain, callback, options
|
84
|
-
end
|
70
|
+
yield callback, options
|
85
71
|
end
|
86
72
|
end
|
87
73
|
|
88
74
|
def validate_callback_options!(action, format)
|
89
|
-
validate!(:action_or_actions, action)
|
90
|
-
validate!(:format_or_formats, format)
|
75
|
+
validate!(:action_or_actions, action) unless action.nil?
|
76
|
+
validate!(:format_or_formats, format) unless format.nil?
|
91
77
|
end
|
92
78
|
|
93
|
-
def
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
# set_callback(chain, :before, callback, options)
|
99
|
-
# end
|
100
|
-
# end
|
101
|
-
#
|
102
|
-
# def self.prepend_before_act(*callbacks, action: nil, format: nil, &block)
|
103
|
-
# validate_callback_options!(action, format)
|
104
|
-
# configure_callbacks(callbacks, action, format, block) do |chain, callback, options|
|
105
|
-
# set_callback(chain, :before, callback, options.merge!(prepend: true))
|
106
|
-
# end
|
107
|
-
# end
|
108
|
-
<<-RUBY, __FILE__, __LINE__ + 1
|
109
|
-
def self.#{kind}_act(*callbacks, action: nil, format: nil, &block)
|
110
|
-
validate_callback_options!(action, format)
|
111
|
-
configure_callbacks(callbacks, action, format, block) do |chain, callback, options|
|
112
|
-
set_callback(chain, :#{kind}, callback, options)
|
113
|
-
end
|
79
|
+
def generate_act_callback_methods
|
80
|
+
ActiveSupport::CodeGenerator.batch(singleton_class, __FILE__, __LINE__) do |owner|
|
81
|
+
%i[before after around].each do |kind|
|
82
|
+
owner.define_cached_method(:"append_act_#{kind}", namespace: :mime_callbacks) do |batch|
|
83
|
+
batch << act_callback_kind_template(kind, append: true)
|
114
84
|
end
|
85
|
+
owner.define_cached_method(:"prepend_act_#{kind}", namespace: :mime_callbacks) do |batch|
|
86
|
+
batch << act_callback_kind_template(kind, append: false)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
# as: check against the defined method in owner, code only generated after #batch block is yielded
|
91
|
+
ActiveSupport::CodeGenerator.batch(singleton_class, __FILE__, __LINE__) do |owner|
|
92
|
+
%i[before after around].each do |kind|
|
93
|
+
owner.define_cached_method(:"act_#{kind}", as: :"append_act_#{kind}", namespace: :mime_callbacks)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
115
97
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
98
|
+
def act_callback_kind_template(kind, append:)
|
99
|
+
type = append ? "append" : "prepend"
|
100
|
+
<<-RUBY
|
101
|
+
def #{type}_act_#{kind}(*callbacks, action: nil, format: nil, &block)
|
102
|
+
validate_callback_options!(action, format)
|
103
|
+
configure_callbacks(callbacks, action, format, block) do |callback, options|
|
104
|
+
set_callback(:act, :#{kind}, callback, options.merge!(prepend: #{!append}))
|
121
105
|
end
|
122
|
-
|
123
|
-
|
106
|
+
end
|
107
|
+
RUBY
|
124
108
|
end
|
125
109
|
end
|
126
110
|
|
127
111
|
# Callbacks invocation sequence depends on the order of callback definition.
|
128
|
-
# (except for callbacks with `format` filter).
|
129
112
|
#
|
130
113
|
# @example callbacks with/without action filter
|
131
|
-
#
|
132
|
-
#
|
133
|
-
#
|
114
|
+
# act_before :my_act_before_one
|
115
|
+
# act_before :my_act_before_two, action: :create
|
116
|
+
# act_before :my_act_before_three
|
134
117
|
#
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
118
|
+
# act_around :my_act_around_one
|
119
|
+
# act_around :my_act_around_two, action: :create
|
120
|
+
# act_around :my_act_around_three
|
138
121
|
#
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
122
|
+
# act_after :my_act_after_one
|
123
|
+
# act_after :my_act_after_two, action: :create
|
124
|
+
# act_after :my_act_after_three
|
142
125
|
#
|
143
126
|
# # actual sequence:
|
144
|
-
# # -
|
145
|
-
# # -
|
146
|
-
# # -
|
147
|
-
# # -
|
148
|
-
# # -
|
149
|
-
# # -
|
150
|
-
# # -
|
151
|
-
# # -
|
152
|
-
# # -
|
127
|
+
# # - my_act_before_one
|
128
|
+
# # - my_act_before_two
|
129
|
+
# # - my_act_before_three
|
130
|
+
# # - my_act_around_one
|
131
|
+
# # - my_act_around_two
|
132
|
+
# # - my_act_around_three
|
133
|
+
# # - my_act_after_three
|
134
|
+
# # - my_act_after_two
|
135
|
+
# # - my_act_after_one
|
153
136
|
#
|
154
137
|
# @example callbacks with format filter
|
155
|
-
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
#
|
138
|
+
# act_before :my_act_before_one
|
139
|
+
# act_before :my_act_before_two, action: :create
|
140
|
+
# act_before :my_act_before_three, action: :create, format: :html
|
141
|
+
# act_before :my_act_before_four
|
159
142
|
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
#
|
163
|
-
#
|
143
|
+
# act_around :my_act_around_one
|
144
|
+
# act_around :my_act_around_two, action: :create, format: :html
|
145
|
+
# act_around :my_act_around_three, action: :create
|
146
|
+
# act_around :my_act_around_four
|
164
147
|
#
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
148
|
+
# act_after :my_act_after_one, format: :html
|
149
|
+
# act_after :my_act_after_two
|
150
|
+
# act_after :my_act_after_three, action: :create
|
151
|
+
# act_after :my_act_after_four
|
169
152
|
#
|
170
153
|
# # actual sequence:
|
171
|
-
# # -
|
172
|
-
# # -
|
173
|
-
# # -
|
174
|
-
# # -
|
175
|
-
# # -
|
176
|
-
# # -
|
177
|
-
# # -
|
178
|
-
# # -
|
179
|
-
# # -
|
180
|
-
# # -
|
181
|
-
# # -
|
182
|
-
# # -
|
154
|
+
# # - my_act_before_one
|
155
|
+
# # - my_act_before_two
|
156
|
+
# # - my_act_before_four
|
157
|
+
# # - my_act_before_three
|
158
|
+
# # - my_act_around_one
|
159
|
+
# # - my_act_around_two
|
160
|
+
# # - my_act_around_three
|
161
|
+
# # - my_act_around_four
|
162
|
+
# # - my_act_after_four
|
163
|
+
# # - my_act_after_three
|
164
|
+
# # - my_act_after_two
|
165
|
+
# # - my_act_after_one
|
183
166
|
#
|
184
|
-
def run_act_callbacks(format)
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
run_callbacks format_chain do
|
191
|
-
yield if block_given?
|
192
|
-
end
|
193
|
-
end
|
194
|
-
else
|
195
|
-
run_callbacks action_chain do
|
196
|
-
yield if block_given?
|
197
|
-
end
|
167
|
+
def run_act_callbacks(action:, format:)
|
168
|
+
@_act_action = action.to_sym
|
169
|
+
@_act_format = format.to_sym
|
170
|
+
|
171
|
+
run_callbacks :act do
|
172
|
+
yield if block_given?
|
198
173
|
end
|
199
174
|
end
|
200
175
|
end
|
@@ -6,16 +6,6 @@ require "active_support/deprecation"
|
|
6
6
|
|
7
7
|
module MimeActor
|
8
8
|
def self.deprecator
|
9
|
-
@deprecator ||= ActiveSupport::Deprecation.new("0.
|
9
|
+
@deprecator ||= ActiveSupport::Deprecation.new("0.8.0", "MimeActor")
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
13
|
-
[
|
14
|
-
[MimeActor::Rescue::ClassMethods, { rescue_actor: "use #rescue_actor instance method" }],
|
15
|
-
[MimeActor::Scene::ClassMethods, { act_on_format: :respond_act_to }],
|
16
|
-
[MimeActor::Stage::ClassMethods, { actor?: "no longer supported, use Object#respond_to?" }],
|
17
|
-
[MimeActor::Stage::ClassMethods, { dispatch_cue: "no longer support anonymous proc with rescue" }],
|
18
|
-
[MimeActor::Stage::ClassMethods, { dispatch_act: "no longer support anonymous proc with rescue" }]
|
19
|
-
].each do |klazz, *args|
|
20
|
-
MimeActor.deprecator.deprecate_methods(klazz, *args)
|
21
|
-
end
|
data/lib/mime_actor/errors.rb
CHANGED
data/lib/mime_actor/logging.rb
CHANGED
@@ -2,9 +2,12 @@
|
|
2
2
|
|
3
3
|
# :markup: markdown
|
4
4
|
|
5
|
+
# required by active_support/tagged_logging
|
6
|
+
require "active_support/version"
|
7
|
+
require "active_support/isolated_execution_state" if ActiveSupport::VERSION::MAJOR >= 7
|
8
|
+
|
5
9
|
require "active_support/concern"
|
6
10
|
require "active_support/configurable"
|
7
|
-
require "active_support/isolated_execution_state" # required by active_support/logger
|
8
11
|
require "active_support/logger"
|
9
12
|
require "active_support/tagged_logging"
|
10
13
|
|
@@ -18,7 +21,14 @@ module MimeActor
|
|
18
21
|
include ActiveSupport::Configurable
|
19
22
|
|
20
23
|
included do
|
21
|
-
|
24
|
+
default_logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new($stdout))
|
25
|
+
if ActiveSupport::VERSION::MAJOR >= 7
|
26
|
+
config_accessor :logger, default: default_logger
|
27
|
+
else
|
28
|
+
config_accessor :logger do
|
29
|
+
default_logger
|
30
|
+
end
|
31
|
+
end
|
22
32
|
end
|
23
33
|
|
24
34
|
private
|
data/lib/mime_actor/railtie.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
module MimeActor
|
6
6
|
class Railtie < Rails::Railtie
|
7
7
|
initializer "mime_actor.deprecator", before: :load_environment_config do |app|
|
8
|
-
app.deprecators[:mime_actor] = MimeActor.deprecator
|
8
|
+
app.deprecators[:mime_actor] = MimeActor.deprecator if Rails::VERSION::MAJOR >= 7
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
data/lib/mime_actor/rescue.rb
CHANGED
@@ -6,9 +6,7 @@ require "mime_actor/dispatcher"
|
|
6
6
|
require "mime_actor/validator"
|
7
7
|
|
8
8
|
require "active_support/concern"
|
9
|
-
require "active_support/core_ext/array/wrap"
|
10
9
|
require "active_support/core_ext/module/attribute_accessors"
|
11
|
-
require "active_support/core_ext/object/blank"
|
12
10
|
require "active_support/core_ext/string/inflections"
|
13
11
|
|
14
12
|
module MimeActor
|
@@ -47,13 +45,13 @@ module MimeActor
|
|
47
45
|
#
|
48
46
|
def rescue_act_from(*klazzes, action: nil, format: nil, with: nil, &block)
|
49
47
|
raise ArgumentError, "error filter is required" if klazzes.empty?
|
50
|
-
raise ArgumentError, "provide either with: or a block" unless with.
|
48
|
+
raise ArgumentError, "provide either with: or a block" unless !with.nil? ^ block_given?
|
51
49
|
|
52
|
-
validate!(:callable, with)
|
50
|
+
validate!(:callable, with) unless with.nil?
|
53
51
|
with = block if block_given?
|
54
52
|
|
55
|
-
validate!(:action_or_actions, action)
|
56
|
-
validate!(:format_or_formats, format)
|
53
|
+
validate!(:action_or_actions, action) unless action.nil?
|
54
|
+
validate!(:format_or_formats, format) unless format.nil?
|
57
55
|
|
58
56
|
klazzes.each do |klazz|
|
59
57
|
validate!(:klazz, klazz)
|
@@ -63,72 +61,6 @@ module MimeActor
|
|
63
61
|
actor_rescuers << [error, format, action, with]
|
64
62
|
end
|
65
63
|
end
|
66
|
-
|
67
|
-
# Resolve the error provided with the registered handlers.
|
68
|
-
#
|
69
|
-
# The handled error will be returned to indicate successful handling.
|
70
|
-
#
|
71
|
-
# @param error the error instance to rescue
|
72
|
-
# @param action the `action` filter
|
73
|
-
# @param format the `format` filter
|
74
|
-
# @param context the context to evaluate for rescue handler
|
75
|
-
# @param visited the errors to skip after no rescue handler matched the filter
|
76
|
-
#
|
77
|
-
def rescue_actor(error, action: nil, format: nil, context: self, visited: [])
|
78
|
-
return if visited.include?(error)
|
79
|
-
|
80
|
-
visited << error
|
81
|
-
if (rescuer = dispatch_rescuer(error, format:, action:, context:))
|
82
|
-
rescuer.call(error, format, action)
|
83
|
-
error
|
84
|
-
elsif error&.cause
|
85
|
-
rescue_actor(error.cause, format:, action:, context:, visited:)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
def dispatch_rescuer(error, format:, action:, context:)
|
92
|
-
case rescuer = find_rescuer(error, format:, action:)
|
93
|
-
when Symbol
|
94
|
-
rescuer_method = context.method(rescuer)
|
95
|
-
lambda do |*args|
|
96
|
-
passable_args = rescuer_method.arity.negative? ? args : args.take(rescuer_method.arity)
|
97
|
-
rescuer_method.call(*passable_args)
|
98
|
-
end
|
99
|
-
when Proc
|
100
|
-
lambda do |*args|
|
101
|
-
passable_args = rescuer.arity.negative? ? args : args.take(rescuer.arity)
|
102
|
-
context.instance_exec(*passable_args, &rescuer)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def find_rescuer(error, format:, action:)
|
108
|
-
return unless error
|
109
|
-
|
110
|
-
*_, rescuer = actor_rescuers.reverse_each.detect do |rescuee, format_filter, action_filter|
|
111
|
-
next if action_filter.present? && !Array.wrap(action_filter).include?(action)
|
112
|
-
next if format_filter.present? && !Array.wrap(format_filter).include?(format)
|
113
|
-
next unless (klazz = constantize_rescuee(rescuee))
|
114
|
-
|
115
|
-
error.is_a?(klazz)
|
116
|
-
end
|
117
|
-
rescuer
|
118
|
-
end
|
119
|
-
|
120
|
-
def constantize_rescuee(class_or_name)
|
121
|
-
case class_or_name
|
122
|
-
when String, Symbol
|
123
|
-
begin
|
124
|
-
const_get(class_or_name)
|
125
|
-
rescue NameError
|
126
|
-
class_or_name.safe_constantize
|
127
|
-
end
|
128
|
-
else
|
129
|
-
class_or_name
|
130
|
-
end
|
131
|
-
end
|
132
64
|
end
|
133
65
|
|
134
66
|
# Resolve the error provided with the registered handlers.
|
@@ -159,8 +91,8 @@ module MimeActor
|
|
159
91
|
return unless error
|
160
92
|
|
161
93
|
*_, rescuer = actor_rescuers.reverse_each.detect do |rescuee, format_filter, action_filter|
|
162
|
-
next
|
163
|
-
next
|
94
|
+
next unless action_filter.nil? || Array(action_filter).include?(action)
|
95
|
+
next unless format_filter.nil? || Array(format_filter).include?(format)
|
164
96
|
next unless (klazz = constantize_rescuee(rescuee))
|
165
97
|
|
166
98
|
error.is_a?(klazz)
|