mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-07-09 21:58:42 +02:00
07c8adaf76
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
73 lines
2.2 KiB
Go
73 lines
2.2 KiB
Go
package surf
|
|
|
|
import (
|
|
"github.com/enetx/g"
|
|
"github.com/enetx/g/cmp"
|
|
)
|
|
|
|
// mw represents a middleware wrapper that holds the function itself,
|
|
// its execution priority, and the order in which it was added.
|
|
type mw[T any] struct {
|
|
fn func(T) error // Middleware function
|
|
priority g.Int // Execution priority (lower is higher priority)
|
|
order g.Int // Insertion order (used to stabilize sorting)
|
|
}
|
|
|
|
// middleware is a generic middleware chain manager for type T.
|
|
// It uses a priority heap to manage the execution order of middleware functions.
|
|
type middleware[T any] struct {
|
|
heap *g.Heap[mw[T]] // Heap-ordered middleware functions
|
|
counter g.Int // Monotonic counter to track insertion order
|
|
}
|
|
|
|
// newMiddleware creates a new middleware manager for type T.
|
|
//
|
|
// Returns:
|
|
// - *middleware[T]: a pointer to a new middleware instance
|
|
//
|
|
// Lower priority values execute earlier. For equal priorities, insertion order is preserved.
|
|
func newMiddleware[T any]() *middleware[T] {
|
|
return &middleware[T]{
|
|
heap: g.NewHeap(func(a, b mw[T]) cmp.Ordering {
|
|
return a.priority.Cmp(b.priority).
|
|
Then(a.order.Cmp(b.order))
|
|
}),
|
|
}
|
|
}
|
|
|
|
// add adds a middleware function to the chain with the specified priority.
|
|
//
|
|
// Parameters:
|
|
// - priority int: determines execution order (lower means earlier execution)
|
|
// - fn func(T) error: the middleware function that receives a context of type T
|
|
//
|
|
// Functions with the same priority are executed in the order they were added.
|
|
func (m *middleware[T]) add(priority g.Int, fn func(T) error) {
|
|
m.heap.Push(mw[T]{fn, priority, m.counter})
|
|
m.counter++
|
|
}
|
|
|
|
// run executes all middleware functions in priority order.
|
|
//
|
|
// Parameters:
|
|
// - ctx T: the context value passed to each middleware function
|
|
//
|
|
// Returns:
|
|
// - error: the first error encountered in the chain, or nil if all passed
|
|
//
|
|
// Note:
|
|
// - A clone of the heap is used during execution to avoid mutating the original chain.
|
|
// - Execution stops immediately if any middleware returns a non-nil error.
|
|
func (m *middleware[T]) run(ctx T) error {
|
|
clone := m.heap.Clone()
|
|
|
|
for !clone.Empty() {
|
|
item := clone.Pop().Some()
|
|
if err := item.fn(ctx); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|