class Meddleware

Constants

VERSION

Public Class Methods

new(&block) click to toggle source
# File lib/meddleware.rb, line 4
def initialize(&block)
  instance_eval(&block) if block_given?
end

Public Instance Methods

after(after_klass, *klass_and_args, &block) click to toggle source
# File lib/meddleware.rb, line 21
def after(after_klass, *klass_and_args, &block)
  entry = create_entry(klass_and_args, block)
  i = index(after_klass) || count - 1
  stack.insert(i + 1, entry)
  self
end
append(*klass_and_args, &block)
Alias for: use
before(before_klass, *klass_and_args, &block) click to toggle source
# File lib/meddleware.rb, line 28
def before(before_klass, *klass_and_args, &block)
  entry = create_entry(klass_and_args, block)
  i = index(before_klass) || 0
  stack.insert(i, entry)
  self
end
call(*args) { |*args| ... } click to toggle source
# File lib/meddleware.rb, line 69
def call(*args)
  chain = build_chain
  default_args = args

  traverse = proc do |*args|
    if args.empty?
      args = default_args
    else
      default_args = args
    end

    if chain.empty?
      yield(*args) if block_given?
    else
      middleware = chain.shift

      if middleware.is_a?(Proc) && !middleware.lambda?
        middleware.call(*args)

        # implicit yield
        traverse.call(*args)
      else
        middleware.call(*args, &traverse)
      end
    end
  end
  traverse.call(*args)
end
clear() click to toggle source
# File lib/meddleware.rb, line 61
def clear
  stack.clear
end
count() click to toggle source
# File lib/meddleware.rb, line 56
def count
  stack.count
end
Also aliased as: size
empty?() click to toggle source
# File lib/meddleware.rb, line 65
def empty?
  stack.empty?
end
include?(klass) click to toggle source
# File lib/meddleware.rb, line 35
def include?(klass)
  !!index(klass)
end
prepend(*klass_and_args, &block) click to toggle source
# File lib/meddleware.rb, line 15
def prepend(*klass_and_args, &block)
  entry = create_entry(klass_and_args, block)
  stack.insert(0, entry)
  self
end
remove(klass) click to toggle source
# File lib/meddleware.rb, line 39
def remove(klass)
  stack.reject! { |entry| entry[0] == klass }
  self
end
replace(old_klass, *klass_and_args, &block) click to toggle source
# File lib/meddleware.rb, line 44
def replace(old_klass, *klass_and_args, &block)
  entry = create_entry(klass_and_args, block)
  i = index(old_klass)

  unless i
    raise RuntimeError, "middleware not present: #{old_klass}"
  end

  stack[i] = entry
  self
end
size()
Alias for: count
use(*klass_and_args, &block) click to toggle source
# File lib/meddleware.rb, line 8
def use(*klass_and_args, &block)
  entry = create_entry(klass_and_args, block)
  stack << entry
  self
end
Also aliased as: append

Private Instance Methods

build_chain() click to toggle source
# File lib/meddleware.rb, line 141
def build_chain
  # build the middleware stack
  stack.map do |klass, args, block|
    if klass.is_a? Class
      klass.new(*args, &block)
    else
      if args.nil? || args.empty?
        klass
      else
        # curry args
        ->(*more_args, &block) do
          klass.call(*args, *more_args, &block)
        end
      end
    end
  end
end
create_entry(klass_and_args, block) click to toggle source
# File lib/meddleware.rb, line 109
def create_entry(klass_and_args, block)
  klass, *args = klass_and_args

  if [ klass, block ].compact.count == 0
    raise ArgumentError, 'either a middleware or block must be provided'
  end

  # dedup
  remove(klass || block)

  if klass
    # validate
    if klass.is_a? Class
      unless klass.method_defined?(:call)
        raise ArgumentError, "middleware must implement `.call`: #{klass}"
      end
    else
      unless klass.respond_to?(:call)
        raise ArgumentError, "middleware must respond to `.call`: #{klass}"
      end

      unless block.nil?
        raise ArgumentError, 'can not supply middleware instance and block'
      end
    end

    [ klass, args, block ]
  else
    [ block ]
  end
end
index(klass) click to toggle source
# File lib/meddleware.rb, line 105
def index(klass)
  stack.index {|entry| entry[0] == klass }
end
stack() click to toggle source
# File lib/meddleware.rb, line 101
def stack
  @stack ||= []
end