aboutsummaryrefslogtreecommitdiff
path: root/network/receivepack/hooks/chain.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-26 09:14:59 +0000
committerGravatar Runxi Yu2026-03-26 09:14:59 +0000
commit3d25bda9d5da6814661828adabe8a09f9d01aefb (patch)
treed034e28079333f85e5d7b96d921282eddd4798d6 /network/receivepack/hooks/chain.go
parentobject/id: Empty tree (diff)
signatureNo signature
network/receivepack: Rename from receivepack
Diffstat (limited to 'network/receivepack/hooks/chain.go')
-rw-r--r--network/receivepack/hooks/chain.go51
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
+ }
+}