2024-05-12 22:47:24 +00:00
|
|
|
package threshold
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2024-05-14 08:26:48 +00:00
|
|
|
// Threshold defines a custom uint8 type for representing a threshold.
|
2024-05-12 22:47:24 +00:00
|
|
|
type Threshold uint8
|
|
|
|
|
2024-05-14 08:26:48 +00:00
|
|
|
// Supported thresholds are:
|
2024-05-12 22:47:24 +00:00
|
|
|
const (
|
2024-05-13 08:45:38 +00:00
|
|
|
Simple Threshold = iota
|
|
|
|
OneFifth
|
|
|
|
OneQuarter
|
|
|
|
OneThird
|
|
|
|
OneHalf
|
|
|
|
TwoThirds
|
|
|
|
TwoFifths
|
|
|
|
ThreeQuarters
|
|
|
|
ThreeFifths
|
|
|
|
FourFifths
|
|
|
|
Unanimous
|
2024-05-12 22:47:24 +00:00
|
|
|
)
|
|
|
|
|
2024-05-14 08:26:48 +00:00
|
|
|
// ValidThresholds returns a []Threshold of all supported thresholds.
|
2024-05-12 22:47:24 +00:00
|
|
|
func ValidThresholds() []Threshold {
|
2024-05-13 08:45:38 +00:00
|
|
|
return []Threshold{
|
2024-05-13 10:12:43 +00:00
|
|
|
Simple, Unanimous,
|
2024-05-13 08:45:38 +00:00
|
|
|
OneFifth, OneQuarter, OneThird, OneHalf,
|
|
|
|
TwoFifths, TwoThirds,
|
2024-05-14 08:26:48 +00:00
|
|
|
ThreeQuarters, ThreeFifths,
|
2024-05-13 08:45:38 +00:00
|
|
|
FourFifths,
|
|
|
|
}
|
2024-05-12 22:47:24 +00:00
|
|
|
}
|
|
|
|
|
2024-05-14 08:26:48 +00:00
|
|
|
// FromString takes a string and returns an initialized Threshold or an error
|
|
|
|
// if the string could not be parsed.
|
2024-05-12 22:47:24 +00:00
|
|
|
func FromString(s string) (Threshold, error) {
|
2024-05-13 08:45:38 +00:00
|
|
|
for _, t := range ValidThresholds() {
|
|
|
|
if strings.ToUpper(t.String()) == strings.ToUpper(s) {
|
|
|
|
return t, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Simple, fmt.Errorf("invalid threshold: %s", s)
|
2024-05-12 22:47:24 +00:00
|
|
|
}
|
|
|
|
|
2024-05-14 08:26:48 +00:00
|
|
|
// String implements fmt.Stringer
|
2024-05-12 22:47:24 +00:00
|
|
|
func (t Threshold) String() string {
|
2024-05-13 08:45:38 +00:00
|
|
|
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")
|
|
|
|
}
|
2024-05-12 22:47:24 +00:00
|
|
|
}
|
|
|
|
|
2024-05-14 08:26:48 +00:00
|
|
|
// IsSatisfied takes the number of all votes, yes votes and no votes and
|
|
|
|
// returns a bool indicating if the threshold is satisfied.
|
2024-05-12 22:47:24 +00:00
|
|
|
func (t Threshold) IsSatisfied(totalVotes, yesVotes, noVotes int) bool {
|
2024-05-13 08:45:38 +00:00
|
|
|
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")
|
|
|
|
}
|
2024-05-12 22:47:24 +00:00
|
|
|
}
|