govote/voting/threshold/threshold.go
2024-05-13 12:12:43 +02:00

103 lines
1.8 KiB
Go

package threshold
import (
"fmt"
"strings"
)
type Threshold uint8
const (
Simple Threshold = iota
OneFifth
OneQuarter
OneThird
OneHalf
TwoThirds
TwoFifths
ThreeQuarters
ThreeFifths
FourFifths
Unanimous
)
func ValidThresholds() []Threshold {
return []Threshold{
Simple, Unanimous,
OneFifth, OneQuarter, OneThird, OneHalf,
TwoFifths, TwoThirds,
ThreeFifths, ThreeQuarters, ThreeFifths,
FourFifths,
}
}
func FromString(s string) (Threshold, error) {
for _, t := range ValidThresholds() {
if strings.ToUpper(t.String()) == strings.ToUpper(s) {
return t, nil
}
}
return Simple, fmt.Errorf("invalid threshold: %s", s)
}
func (t Threshold) String() string {
switch t {
case Simple:
return "SIMPLE"
case OneFifth:
return "1/5"
case OneQuarter:
return "1/4"
case OneThird:
return "1/3"
case OneHalf:
return "1/2"
case TwoThirds:
return "2/3"
case TwoFifths:
return "2/5"
case ThreeQuarters:
return "3/4"
case ThreeFifths:
return "3/5"
case FourFifths:
return "4/5"
case Unanimous:
return "ALL"
default:
panic("this code should never be reached")
}
}
func (t Threshold) IsSatisfied(totalVotes, yesVotes, noVotes int) bool {
if totalVotes == 0 {
return false
}
switch t {
case Simple:
return yesVotes > noVotes
case OneFifth:
return yesVotes*5 >= totalVotes
case OneQuarter:
return yesVotes*4 >= totalVotes
case OneThird:
return yesVotes*3 >= totalVotes
case OneHalf:
return yesVotes*2 >= totalVotes
case TwoThirds:
return yesVotes*3 >= totalVotes*2
case TwoFifths:
return yesVotes*5 >= totalVotes*2
case ThreeQuarters:
return yesVotes*4 >= totalVotes*3
case ThreeFifths:
return yesVotes*5 >= totalVotes*3
case FourFifths:
return yesVotes*5 >= totalVotes*4
case Unanimous:
return yesVotes >= totalVotes
default:
panic("this code should never be reached")
}
}