govote/voting/quorum/quorum.go
2024-05-14 10:27:13 +02:00

111 lines
2.2 KiB
Go

package quorum
import (
"fmt"
"strings"
)
// Quorum defines a custom uint8 type for storing a quorum.
type Quorum uint8
// Supported quorums are:
const (
Simple Quorum = iota
OneFifth
OneQuarter
OneThird
OneHalf
TwoFifths
TwoThirds
ThreeQuarters
ThreeFifths
FourFifths
Unanimous
)
// ValidQuorums returns a []Quorum of all supported quorums.
func ValidQuorums() []Quorum {
return []Quorum{
Simple, Unanimous,
OneFifth, OneQuarter, OneThird, OneHalf,
TwoThirds, TwoFifths,
ThreeQuarters, ThreeFifths,
FourFifths,
}
}
// FromString takes a string and returns an initialized Quorum or an error if
// the string could not be parsed.
func FromString(s string) (Quorum, error) {
for _, q := range ValidQuorums() {
if strings.ToUpper(q.String()) == strings.ToUpper(s) {
return q, nil
}
}
return Simple, fmt.Errorf("inalid quorum: %s", s)
}
// String implements fmt.Stringer
func (q Quorum) String() string {
switch q {
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")
}
}
// IsSatisfied takes the number of eligible and actual votes and returns a bool
// indicating if the quroum is satisfied or not.
func (q Quorum) IsSatisfied(possibleVotes, totalVotes int) bool {
if totalVotes == 0 {
return false
}
switch q {
case Simple:
return true
case OneFifth:
return totalVotes*5 >= possibleVotes
case OneQuarter:
return totalVotes*4 >= possibleVotes
case OneThird:
return totalVotes*3 >= possibleVotes
case OneHalf:
return totalVotes*2 >= possibleVotes
case TwoThirds:
return totalVotes*3 >= possibleVotes*2
case TwoFifths:
return totalVotes*5 >= possibleVotes*2
case ThreeQuarters:
return totalVotes*4 >= possibleVotes*3
case ThreeFifths:
return totalVotes*5 >= possibleVotes*3
case FourFifths:
return totalVotes*5 >= possibleVotes*4
case Unanimous:
return totalVotes >= possibleVotes
default:
panic("this code should never be reached")
}
}