-
Notifications
You must be signed in to change notification settings - Fork 3.6k
/
vote.go
145 lines (120 loc) · 2.85 KB
/
vote.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package types
import (
"encoding/json"
"fmt"
"gopkg.in/yaml.v2"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// NewVote creates a new Vote instance
func NewVote(proposalID uint64, voter sdk.AccAddress, option VoteOption) Vote {
return Vote{proposalID, voter, option}
}
func (v Vote) String() string {
out, _ := yaml.Marshal(v)
return string(out)
}
// Votes is a collection of Vote objects
type Votes []Vote
// Equal returns true if two slices (order-dependant) of votes are equal.
func (v Votes) Equal(other Votes) bool {
if len(v) != len(other) {
return false
}
for i, vote := range v {
if !vote.Equal(other[i]) {
return false
}
}
return true
}
func (v Votes) String() string {
if len(v) == 0 {
return "[]"
}
out := fmt.Sprintf("Votes for Proposal %d:", v[0].ProposalID)
for _, vot := range v {
out += fmt.Sprintf("\n %s: %s", vot.Voter, vot.Option)
}
return out
}
// Empty returns whether a vote is empty.
func (v Vote) Empty() bool {
return v.Equal(Vote{})
}
// VoteOptionFromString returns a VoteOption from a string. It returns an error
// if the string is invalid.
func VoteOptionFromString(str string) (VoteOption, error) {
switch str {
case "Yes":
return OptionYes, nil
case "Abstain":
return OptionAbstain, nil
case "No":
return OptionNo, nil
case "NoWithVeto":
return OptionNoWithVeto, nil
default:
return VoteOption(0xff), fmt.Errorf("'%s' is not a valid vote option", str)
}
}
// ValidVoteOption returns true if the vote option is valid and false otherwise.
func ValidVoteOption(option VoteOption) bool {
if option == OptionYes ||
option == OptionAbstain ||
option == OptionNo ||
option == OptionNoWithVeto {
return true
}
return false
}
// Marshal needed for protobuf compatibility.
func (vo VoteOption) Marshal() ([]byte, error) {
return []byte{byte(vo)}, nil
}
// Unmarshal needed for protobuf compatibility.
func (vo *VoteOption) Unmarshal(data []byte) error {
*vo = VoteOption(data[0])
return nil
}
// Marshals to JSON using string.
func (vo VoteOption) MarshalJSON() ([]byte, error) {
return json.Marshal(vo.String())
}
// UnmarshalJSON decodes from JSON assuming Bech32 encoding.
func (vo *VoteOption) UnmarshalJSON(data []byte) error {
var s string
err := json.Unmarshal(data, &s)
if err != nil {
return err
}
bz2, err := VoteOptionFromString(s)
if err != nil {
return err
}
*vo = bz2
return nil
}
// String implements the Stringer interface.
func (vo VoteOption) String() string {
switch vo {
case OptionYes:
return "Yes"
case OptionAbstain:
return "Abstain"
case OptionNo:
return "No"
case OptionNoWithVeto:
return "NoWithVeto"
default:
return ""
}
}
// Format implements the fmt.Formatter interface.
func (vo VoteOption) Format(s fmt.State, verb rune) {
switch verb {
case 's':
s.Write([]byte(vo.String()))
default:
s.Write([]byte(fmt.Sprintf("%v", byte(vo))))
}
}