package middleware
import (
)
type BuildInput struct {
Request interface{}
}
type BuildOutput struct {
Result interface{}
}
type BuildHandler interface {
HandleBuild(ctx context.Context, in BuildInput) (
out BuildOutput, metadata Metadata, err error,
)
}
type BuildMiddleware interface {
ID() string
HandleBuild(ctx context.Context, in BuildInput, next BuildHandler) (
out BuildOutput, metadata Metadata, err error,
)
}
func ( string, func(context.Context, BuildInput, BuildHandler) (BuildOutput, Metadata, error)) BuildMiddleware {
return buildMiddlewareFunc{
id: ,
fn: ,
}
}
type buildMiddlewareFunc struct {
id string
fn func(context.Context, BuildInput, BuildHandler) (BuildOutput, Metadata, error)
}
func ( buildMiddlewareFunc) () string { return .id }
func ( buildMiddlewareFunc) ( context.Context, BuildInput, BuildHandler) (
BuildOutput, Metadata, error,
) {
return .fn(, , )
}
var _ BuildMiddleware = (buildMiddlewareFunc{})
type BuildStep struct {
ids *orderedIDs
}
func () *BuildStep {
return &BuildStep{
ids: newOrderedIDs(),
}
}
var _ Middleware = (*BuildStep)(nil)
func ( *BuildStep) () string {
return "Build stack step"
}
func ( *BuildStep) ( context.Context, interface{}, Handler) (
interface{}, Metadata, error,
) {
:= .ids.GetOrder()
var BuildHandler = buildWrapHandler{Next: }
for := len() - 1; >= 0; -- {
= decoratedBuildHandler{
Next: ,
With: [].(BuildMiddleware),
}
}
:= BuildInput{
Request: ,
}
, , := .HandleBuild(, )
return .Result, ,
}
func ( *BuildStep) ( string) (BuildMiddleware, bool) {
, := .ids.Get()
if ! {
return nil, false
}
return .(BuildMiddleware),
}
func ( *BuildStep) ( BuildMiddleware, RelativePosition) error {
return .ids.Add(, )
}
func ( *BuildStep) ( BuildMiddleware, string, RelativePosition) error {
return .ids.Insert(, , )
}
func ( *BuildStep) ( string, BuildMiddleware) (BuildMiddleware, error) {
, := .ids.Swap(, )
if != nil {
return nil,
}
return .(BuildMiddleware), nil
}
func ( *BuildStep) ( string) (BuildMiddleware, error) {
, := .ids.Remove()
if != nil {
return nil,
}
return .(BuildMiddleware), nil
}
func ( *BuildStep) () []string {
return .ids.List()
}
func ( *BuildStep) () {
.ids.Clear()
}
type buildWrapHandler struct {
Next Handler
}
var _ BuildHandler = (*buildWrapHandler)(nil)
func ( buildWrapHandler) ( context.Context, BuildInput) (
BuildOutput, Metadata, error,
) {
, , := .Next.Handle(, .Request)
return BuildOutput{
Result: ,
}, ,
}
type decoratedBuildHandler struct {
Next BuildHandler
With BuildMiddleware
}
var _ BuildHandler = (*decoratedBuildHandler)(nil)
func ( decoratedBuildHandler) ( context.Context, BuildInput) (
BuildOutput, Metadata, error,
) {
return .With.HandleBuild(, , .Next)
}
type BuildHandlerFunc func(context.Context, BuildInput) (BuildOutput, Metadata, error)
func ( BuildHandlerFunc) ( context.Context, BuildInput) (BuildOutput, Metadata, error) {
return (, )
}
var _ BuildHandler = BuildHandlerFunc(nil)