-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcombinators.go
More file actions
83 lines (66 loc) · 1.93 KB
/
combinators.go
File metadata and controls
83 lines (66 loc) · 1.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package hyperacc
import (
"fmt"
"strings"
"github.com/hyperledger/fabric-contract-api-go/v2/contractapi"
)
// AndRule combines multiple rules with AND logic (all must pass)
type AndRule struct {
rules []Rule
}
// And creates a rule that requires all nested rules to pass
func And(rules ...Rule) *AndRule {
return &AndRule{rules: rules}
}
// Check checks all rules (all must pass)
func (r *AndRule) Check(ctx contractapi.TransactionContextInterface) error {
var errors []string
for i, rule := range r.rules {
if err := rule.Check(ctx); err != nil {
errors = append(errors, fmt.Sprintf("rule %d: %v", i+1, err))
}
}
if len(errors) > 0 {
return NewAccessError(fmt.Sprintf("AND rule failed: %s", strings.Join(errors, "; ")))
}
return nil
}
// OrRule combines multiple rules with OR logic (at least one must pass)
type OrRule struct {
rules []Rule
}
// Or creates a rule that requires at least one nested rule to pass
func Or(rules ...Rule) *OrRule {
return &OrRule{rules: rules}
}
// Check checks rules (at least one must pass)
func (r *OrRule) Check(ctx contractapi.TransactionContextInterface) error {
if len(r.rules) == 0 {
return NewAccessError("OR rule: no rules defined")
}
var errors []string
for i, rule := range r.rules {
if err := rule.Check(ctx); err == nil {
return nil // At least one rule passed
} else {
errors = append(errors, fmt.Sprintf("rule %d: %v", i+1, err))
}
}
return NewAccessError(fmt.Sprintf("OR rule failed: none of the rules passed: %s", strings.Join(errors, "; ")))
}
// NotRule inverts a rule
type NotRule struct {
rule Rule
}
// Not creates a rule that inverts the result of a nested rule
func Not(rule Rule) *NotRule {
return &NotRule{rule: rule}
}
// Check inverts the result of rule checking
func (r *NotRule) Check(ctx contractapi.TransactionContextInterface) error {
err := r.rule.Check(ctx)
if err == nil {
return NewAccessError("NOT rule: rule should not pass")
}
return nil
}