diff options
| author | 2026-03-26 09:14:59 +0000 | |
|---|---|---|
| committer | 2026-03-26 09:14:59 +0000 | |
| commit | 3d25bda9d5da6814661828adabe8a09f9d01aefb (patch) | |
| tree | d034e28079333f85e5d7b96d921282eddd4798d6 /network/receivepack/hooks/chain.go | |
| parent | object/id: Empty tree (diff) | |
| signature | No signature | |
network/receivepack: Rename from receivepack
Diffstat (limited to 'network/receivepack/hooks/chain.go')
| -rw-r--r-- | network/receivepack/hooks/chain.go | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/network/receivepack/hooks/chain.go b/network/receivepack/hooks/chain.go new file mode 100644 index 00000000..f98c06f8 --- /dev/null +++ b/network/receivepack/hooks/chain.go @@ -0,0 +1,51 @@ +package hooks + +import ( + "context" + "fmt" + + receivepack "codeberg.org/lindenii/furgit/network/receivepack" +) + +// Chain combines hooks by running them in order and intersecting their +// decisions. The first rejecting message for each update is preserved. +func Chain(hooks ...receivepack.Hook) receivepack.Hook { + return func( + ctx context.Context, + req receivepack.HookRequest, + ) ([]receivepack.UpdateDecision, error) { + decisions := make([]receivepack.UpdateDecision, len(req.Updates)) + for i := range decisions { + decisions[i].Accept = true + } + + for _, hook := range hooks { + if hook == nil { + continue + } + + hookDecisions, err := hook(ctx, req) + if err != nil { + return nil, err + } + + if len(hookDecisions) != len(req.Updates) { + return nil, fmt.Errorf("hook returned %d decisions for %d updates", len(hookDecisions), len(req.Updates)) + } + + for i, decision := range hookDecisions { + if decision.Accept { + continue + } + + if decisions[i].Accept { + decisions[i].Message = decision.Message + } + + decisions[i].Accept = false + } + } + + return decisions, nil + } +} |
