65 lines
1.9 KiB
Go
65 lines
1.9 KiB
Go
package validators
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"gitea.maximumdirect.net/eric/notarius/internal/core/artifacts"
|
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
|
)
|
|
|
|
const (
|
|
ReasonApproved = "approved"
|
|
)
|
|
|
|
func Approved(candidateIndex int) contracts.ValidationDecision {
|
|
return contracts.ValidationDecision{
|
|
CandidateIndex: candidateIndex,
|
|
Approved: true,
|
|
ReasonCode: ReasonApproved,
|
|
Message: ReasonApproved,
|
|
}
|
|
}
|
|
|
|
func Rejected(candidateIndex int, reasonCode string, message string) contracts.ValidationDecision {
|
|
return contracts.ValidationDecision{
|
|
CandidateIndex: candidateIndex,
|
|
Approved: false,
|
|
ReasonCode: strings.TrimSpace(reasonCode),
|
|
Message: strings.TrimSpace(message),
|
|
}
|
|
}
|
|
|
|
func EnforceDecisionCardinality(candidates []artifacts.Candidate, decisions []contracts.ValidationDecision) error {
|
|
if len(candidates) != len(decisions) {
|
|
return fmt.Errorf("validator returned %d decisions for %d candidates", len(decisions), len(candidates))
|
|
}
|
|
|
|
expected := make(map[int]struct{}, len(candidates))
|
|
for _, candidate := range candidates {
|
|
if _, ok := expected[candidate.Index]; ok {
|
|
return fmt.Errorf("candidate index %d is duplicated", candidate.Index)
|
|
}
|
|
expected[candidate.Index] = struct{}{}
|
|
}
|
|
|
|
seen := make(map[int]struct{}, len(decisions))
|
|
for _, decision := range decisions {
|
|
if _, ok := expected[decision.CandidateIndex]; !ok {
|
|
return fmt.Errorf("validator returned decision for unknown candidate index %d", decision.CandidateIndex)
|
|
}
|
|
if _, ok := seen[decision.CandidateIndex]; ok {
|
|
return fmt.Errorf("validator returned duplicate decision for candidate index %d", decision.CandidateIndex)
|
|
}
|
|
seen[decision.CandidateIndex] = struct{}{}
|
|
}
|
|
|
|
for candidateIndex := range expected {
|
|
if _, ok := seen[candidateIndex]; !ok {
|
|
return fmt.Errorf("validator did not return decision for candidate index %d", candidateIndex)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|