lib/jeanine/callbacks.rb in jeanine-0.4.0 vs lib/jeanine/callbacks.rb in jeanine-0.5.0
- old
+ new
@@ -1,29 +1,106 @@
module Jeanine
module Callbacks
- def _callbacks
- @_callbacks ||= {
- before: [],
- after: [],
- before_all: [],
- after_all: []
- }
+ def self.included(klass)
+ klass.extend InstanceMethods
+ klass.prepend EvaluationMethods
end
- def before(*paths, &block)
- _register_callback(:before, paths, &block)
- end
+ module InstanceMethods
+ def _callbacks
+ @_callbacks ||= {
+ before: [],
+ after: [],
+ before_all: [],
+ after_all: []
+ }
+ end
- def after(*paths, &block)
- _register_callback(:after, paths, &block)
+ def before(*paths, &block)
+ _register_callback(:before, paths, &block)
+ end
+
+ def after(*paths, &block)
+ _register_callback(:after, paths, &block)
+ end
+
+ private
+
+ def _register_callback(type, paths = [], &block)
+ if paths == []
+ _callbacks["#{type}_all".to_sym] << { block: block }
+ else
+ _callbacks[type] << { paths: paths, block: block }
+ end
+ end
end
- private
- def _register_callback(type, paths = [], &block)
- if paths == []
- _callbacks["#{type}_all".to_sym] << { block: block }
- else
- _callbacks[type] << { paths: paths, block: block }
+ module EvaluationMethods
+ def route_eval
+ before_find_route!
+ route = find_route
+
+ if route
+ before_evaluate_route!
+ result = instance_eval(&route[:block])
+ @response.write(result)
+ after_evaluate_route!
+ else
+ @response.status = 404
+ end
+ after_response!
+ @response.complete!
+ end
+
+ private
+
+ def before_find_route!
+ run_before_callbacks!(:before_all)
+ end
+
+ def before_evaluate_route!
+ run_before_callbacks!(:before)
+ end
+
+ def after_evaluate_route!
+ run_after_callbacks!(:after)
+ end
+
+ def after_response!
+ run_after_callbacks!(:after_all)
+ end
+
+ def run_before_callbacks!(type)
+ if type == :before_all
+ self.class._callbacks[type].each { |callback| eval_callback(&callback[:block]) }
+ else
+ matching_callbacks(type) do |callback|
+ eval_callback(&callback[:block])
+ end
+ end
+ end
+
+ def run_after_callbacks!(type)
+ if type == :after_all
+ self.class._callbacks[type].each { |callback| eval_callback(&callback[:block]) }
+ else
+ matching_callbacks(type) do |callback|
+ eval_callback(&callback[:block])
+ end
+ end
+ end
+
+ def matching_callbacks(type)
+ self.class._callbacks[type].select do |callback|
+ paths = callback[:paths]
+ if paths.detect { |path| path.match?(@request.path_info) }
+ yield callback
+ end
+ end
+ end
+
+ def eval_callback(*args, &callback)
+ instance_exec(*args, &callback)
end
end
end
end