Files
notarius/internal/framework/validate/validate.go

65 lines
1.9 KiB
Go

package validate
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.ArtifactCandidate, 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
}