package ircv3 type Handler interface { Handle(w MessageWriter, m *Event) } type HandlerFunc func(w MessageWriter, e *Event) func (h HandlerFunc) Handle(w MessageWriter, e *Event) { h(w, e) } type MessageWriter interface { WriteMessage(msg *Message) error } type Middleware func(next Handler) Handler type Middlewares []func(Handler) Handler // Chain returns a Middlewares type from a slice of middleware handlers. func Chain(middlewares ...func(Handler) Handler) Middlewares { return Middlewares(middlewares) } // Handler builds and returns a http.Handler from the chain of middlewares, // with `h http.Handler` as the final handler. func (mws Middlewares) Handler(h Handler) Handler { return &ChainHandler{h, chain(mws, h), mws} } // HandlerFunc builds and returns a http.Handler from the chain of middlewares, // with `h http.Handler` as the final handler. func (mws Middlewares) HandlerFunc(h HandlerFunc) Handler { return &ChainHandler{h, chain(mws, h), mws} } // ChainHandler is a http.Handler with support for handler composition and // execution. type ChainHandler struct { Endpoint Handler chain Handler Middlewares Middlewares } func (c *ChainHandler) Handle(w MessageWriter, e *Event) { c.chain.Handle(w, e) } // chain builds a http.Handler composed of an inline middleware stack and endpoint // handler in the order they are passed. func chain(middlewares []func(Handler) Handler, endpoint Handler) Handler { // Return ahead of time if there aren't any middlewares for the chain if len(middlewares) == 0 { return endpoint } // Wrap the end handler with the middleware chain h := middlewares[len(middlewares)-1](endpoint) for i := len(middlewares) - 2; i >= 0; i-- { h = middlewares[i](h) } return h }