1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
# frozen_string_literal: true
# Released under the MIT License.
# Copyright, 2019-2024, by Samuel Williams.
require_relative "../middleware"
module Protocol
module HTTP
class Middleware
# A convenient interface for constructing middleware stacks.
class Builder
# Initialize the builder with the given default application.
#
# @parameter default_app [Object] The default application to use if no middleware is specified.
def initialize(default_app = NotFound)
@use = []
@app = default_app
end
# Use the given middleware with the given arguments and options.
#
# @parameter middleware [Class | Object] The middleware class to use.
# @parameter arguments [Array] The arguments to pass to the middleware constructor.
# @parameter options [Hash] The options to pass to the middleware constructor.
# @parameter block [Proc] The block to pass to the middleware constructor.
def use(middleware, *arguments, **options, &block)
@use << proc {|app| middleware.new(app, *arguments, **options, &block)}
end
# Specify the (default) middleware application to use.
#
# @parameter app [Middleware] The application to use if no middleware is able to handle the request.
def run(app)
@app = app
end
# Convert the builder to an application by chaining the middleware together.
#
# @returns [Middleware] The application.
def to_app
@use.reverse.inject(@app) {|app, use| use.call(app)}
end
end
# Build a middleware application using the given block.
def self.build(&block)
builder = Builder.new
if block_given?
if block.arity == 0
builder.instance_exec(&block)
else
yield builder
end
end
return builder.to_app
end
end
end
end
|