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