lib/faraday/builder.rb in faraday-0.5.7 vs lib/faraday/builder.rb in faraday-0.6.0
- old
+ new
@@ -1,62 +1,86 @@
module Faraday
# Possibly going to extend this a bit.
#
- # Faraday::Connection.new(:url => 'http://sushi.com') do |b|
- # b.request :yajl # Faraday::Request::Yajl
- # b.adapter :logger # Faraday::Adapter::Logger
- # b.response :yajl # Faraday::Response::Yajl
+ # Faraday::Connection.new(:url => 'http://sushi.com') do |builder|
+ # builder.request :url_encoded # Faraday::Request::UrlEncoded
+ # builder.adapter :net_http # Faraday::Adapter::NetHttp
# end
class Builder
attr_accessor :handlers
def self.create
- block = block_given? ? Proc.new : nil
- Builder.new(&block)
+ new { |builder| yield builder }
end
- def self.inner_app
- lambda do |env|
- env[:parallel_manager] ? env[:response] : env[:response].finish(env)
+ # borrowed from ActiveSupport::Dependencies::Reference &
+ # ActionDispatch::MiddlewareStack::Middleware
+ class Handler
+ @@constants = Hash.new { |h, k|
+ h[k] = k.respond_to?(:constantize) ? k.constantize : Object.const_get(k)
+ }
+
+ attr_reader :name
+
+ def initialize(klass, *args, &block)
+ @name = klass.to_s
+ @@constants[@name] = klass if klass.respond_to?(:name)
+ @args, @block = args, block
end
+
+ def klass() @@constants[@name] end
+ def inspect() @name end
+
+ def ==(other)
+ if other.respond_to? :name
+ klass == other
+ else
+ @name == other.to_s
+ end
+ end
+
+ def build(app)
+ klass.new(app, *@args, &@block)
+ end
end
def initialize(handlers = [])
@handlers = handlers
- build(Proc.new) if block_given?
+ if block_given?
+ build(&Proc.new)
+ elsif @handlers.empty?
+ # default stack, if nothing else is configured
+ self.request :url_encoded
+ self.adapter Faraday.default_adapter
+ end
end
def build(options = {})
- inner = @handlers.shift
- if !options[:keep]
- @handlers.clear
- end
+ @handlers.clear unless options[:keep]
yield self if block_given?
- run(inner || self.class.inner_app)
end
- def [](index)
- # @handlers are stored in reverse order
- @handlers[-(index+1)]
+ def [](idx)
+ @handlers[idx]
end
- def run(app)
- @handlers.unshift app
+ def ==(other)
+ other.is_a?(self.class) && @handlers == other.handlers
end
- def to_app
- if @handlers.empty?
- build { |b| b.adapter Faraday.default_adapter }
- end
+ def dup
+ self.class.new(@handlers.dup)
+ end
- inner_app = @handlers.first
- @handlers[1..-1].inject(inner_app) { |app, middleware| middleware.call(app) }
+ def to_app(inner_app)
+ # last added handler is the deepest and thus closest to the inner app
+ @handlers.reverse.inject(inner_app) { |app, handler| handler.build(app) }
end
def use(klass, *args)
block = block_given? ? Proc.new : nil
- run(lambda { |app| klass.new(app, *args, &block) })
+ @handlers << self.class::Handler.new(klass, *args, &block)
end
def request(key, *args)
block = block_given? ? Proc.new : nil
use_symbol(Faraday::Request, key, *args, &block)
@@ -70,19 +94,44 @@
def adapter(key, *args)
block = block_given? ? Proc.new : nil
use_symbol(Faraday::Adapter, key, *args, &block)
end
+ ## methods to push onto the various positions in the stack:
+
+ def insert(index, *args, &block)
+ index = assert_index(index)
+ handler = self.class::Handler.new(*args, &block)
+ @handlers.insert(index, handler)
+ end
+
+ alias_method :insert_before, :insert
+
+ def insert_after(index, *args, &block)
+ index = assert_index(index)
+ insert(index + 1, *args, &block)
+ end
+
+ def swap(index, *args, &block)
+ index = assert_index(index)
+ @handlers.delete_at(index)
+ insert(index, *args, &block)
+ end
+
+ def delete(handler)
+ @handlers.delete(handler)
+ end
+
+ private
+
def use_symbol(mod, key, *args)
block = block_given? ? Proc.new : nil
use(mod.lookup_module(key), *args, &block)
end
- def ==(other)
- other.is_a?(self.class) && @handlers == other.handlers
- end
-
- def dup
- self.class.new(@handlers.dup)
+ def assert_index(index)
+ idx = index.is_a?(Integer) ? index : @handlers.index(index)
+ raise "No such handler: #{index.inspect}" unless idx
+ idx
end
end
end