class WoolenCommon::Middleware::Builder

This provides a DSL for building up a stack of middlewares.

This code is based heavily off of `Rack::Builder` and `ActionDispatch::MiddlewareStack` in Rack and Rails, respectively.

# Usage

Building a middleware stack is very easy:

app = Middleware::Builder.new do
  use A
  use B
end

# Call the middleware
app.call(7)

Public Class Methods

new(opts=nil, &block) click to toggle source

Initializes the builder. An optional block can be passed which will be evaluated in the context of the instance.

Example:

Builder.new do
  use A
  use B
end

@param [Hash] opts Options hash @option opts [Class] :runner_class The class to wrap the middleware stack

in which knows how to run them.

@yield [] Evaluated in this instance which allows you to use methods

like {#use} and such.
# File lib/woolen_common/abstract_middleware/builder.rb, line 36
def initialize(opts=nil, &block)
    opts ||= {}
    @runner_class = opts[:runner_class] || Runner
    instance_eval(&block) if block_given?
end

Public Instance Methods

call(env=nil) click to toggle source

Runs the builder stack with the given environment.

# File lib/woolen_common/abstract_middleware/builder.rb, line 103
def call(env=nil)
    to_app.call(env)
end
delete(index) click to toggle source

Deletes the given middleware object or index

# File lib/woolen_common/abstract_middleware/builder.rb, line 97
def delete(index)
    index = self.index(index) unless index.is_a?(Integer)
    stack.delete_at(index)
end
flatten() click to toggle source

Returns a mergeable version of the builder. If `use` is called with the return value of this method, then the stack will merge, instead of being treated as a separate single middleware.

# File lib/woolen_common/abstract_middleware/builder.rb, line 45
def flatten
    lambda do |env|
        self.call(env)
    end
end
insert(index, middleware, *args, &block) click to toggle source

Inserts a middleware at the given index or directly before the given middleware object.

# File lib/woolen_common/abstract_middleware/builder.rb, line 69
def insert(index, middleware, *args, &block)
    index = self.index(index) unless index.is_a?(Integer)
    raise "no such middleware to insert before: #{index.inspect}" unless index
    stack.insert(index, [middleware, args, block])
end
Also aliased as: insert_before
insert_after(index, middleware, *args, &block) click to toggle source

Inserts a middleware after the given index or middleware object.

# File lib/woolen_common/abstract_middleware/builder.rb, line 78
def insert_after(index, middleware, *args, &block)
    index = self.index(index) unless index.is_a?(Integer)
    raise "no such middleware to insert after: #{index.inspect}" unless index
    insert(index + 1, middleware, *args, &block)
end
insert_before(index, middleware, *args, &block)
Alias for: insert
replace(index, middleware, *args, &block) click to toggle source

Replaces the given middleware object or index with the new middleware.

# File lib/woolen_common/abstract_middleware/builder.rb, line 86
def replace(index, middleware, *args, &block)
    if index.is_a?(Integer)
        delete(index)
        insert(index, middleware, *args, &block)
    else
        insert_before(index, middleware, *args, &block)
        delete(index)
    end
end
use(middleware, *args, &block) click to toggle source

Adds a middleware class to the middleware stack. Any additional args and a block, if given, are saved and passed to the initializer of the middleware.

@param [Class] middleware The middleware class

# File lib/woolen_common/abstract_middleware/builder.rb, line 56
def use(middleware, *args, &block)
    if middleware.kind_of?(Builder)
        # Merge in the other builder's stack into our own
        self.stack.concat(middleware.stack)
    else
        self.stack << [middleware, args, block]
    end

    self
end

Protected Instance Methods

index(object) click to toggle source

Returns the numeric index for the given middleware object.

@param [Object] object The item to find the index for @return [Integer]

# File lib/woolen_common/abstract_middleware/builder.rb, line 113
def index(object)
    stack.each_with_index do |item, i|
        return i if item[0] == object
    end

    nil
end
stack() click to toggle source

Returns the current stack of middlewares. You probably won't need to use this directly, and it's recommended that you don't.

@return [Array]

# File lib/woolen_common/abstract_middleware/builder.rb, line 125
def stack
    @stack ||= []
end
to_app() click to toggle source

Converts the builder stack to a runnable action sequence.

@return [Object] A callable object

# File lib/woolen_common/abstract_middleware/builder.rb, line 132
def to_app
    @runner_class.new(stack.dup)
end