github.com/Finschia/finschia-sdk@v0.49.1/x/gov/types/vote.go (about) 1 package types 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 8 yaml "gopkg.in/yaml.v2" 9 10 sdk "github.com/Finschia/finschia-sdk/types" 11 ) 12 13 // NewVote creates a new Vote instance 14 // 15 //nolint:interfacer 16 func NewVote(proposalID uint64, voter sdk.AccAddress, options WeightedVoteOptions) Vote { 17 return Vote{ProposalId: proposalID, Voter: voter.String(), Options: options} 18 } 19 20 func (v Vote) String() string { 21 out, _ := yaml.Marshal(v) 22 return string(out) 23 } 24 25 // Votes is a collection of Vote objects 26 type Votes []Vote 27 28 // Equal returns true if two slices (order-dependant) of votes are equal. 29 func (v Votes) Equal(other Votes) bool { 30 if len(v) != len(other) { 31 return false 32 } 33 34 for i, vote := range v { 35 if vote.String() != other[i].String() { 36 return false 37 } 38 } 39 40 return true 41 } 42 43 func (v Votes) String() string { 44 if len(v) == 0 { 45 return "[]" 46 } 47 out := fmt.Sprintf("Votes for Proposal %d:", v[0].ProposalId) 48 for _, vot := range v { 49 out += fmt.Sprintf("\n %s: %s", vot.Voter, vot.Options) 50 } 51 return out 52 } 53 54 // Empty returns whether a vote is empty. 55 func (v Vote) Empty() bool { 56 return v.String() == Vote{}.String() 57 } 58 59 // NewNonSplitVoteOption creates a single option vote with weight 1 60 func NewNonSplitVoteOption(option VoteOption) WeightedVoteOptions { 61 return WeightedVoteOptions{{option, sdk.NewDec(1)}} 62 } 63 64 func (v WeightedVoteOption) String() string { 65 out, err := json.Marshal(v) 66 if err != nil { 67 panic(err) 68 } 69 return string(out) 70 } 71 72 // WeightedVoteOptions describes array of WeightedVoteOptions 73 type WeightedVoteOptions []WeightedVoteOption 74 75 func (v WeightedVoteOptions) String() (out string) { 76 for _, opt := range v { 77 out += opt.String() + "\n" 78 } 79 80 return strings.TrimSpace(out) 81 } 82 83 // ValidWeightedVoteOption returns true if the sub vote is valid and false otherwise. 84 func ValidWeightedVoteOption(option WeightedVoteOption) bool { 85 if !option.Weight.IsPositive() || option.Weight.GT(sdk.NewDec(1)) { 86 return false 87 } 88 return ValidVoteOption(option.Option) 89 } 90 91 // VoteOptionFromString returns a VoteOption from a string. It returns an error 92 // if the string is invalid. 93 func VoteOptionFromString(str string) (VoteOption, error) { 94 option, ok := VoteOption_value[str] 95 if !ok { 96 return OptionEmpty, fmt.Errorf("'%s' is not a valid vote option, available options: yes/no/no_with_veto/abstain", str) 97 } 98 return VoteOption(option), nil 99 } 100 101 // WeightedVoteOptionsFromString returns weighted vote options from string. It returns an error 102 // if the string is invalid. 103 func WeightedVoteOptionsFromString(str string) (WeightedVoteOptions, error) { 104 options := WeightedVoteOptions{} 105 for _, option := range strings.Split(str, ",") { 106 fields := strings.Split(option, "=") 107 option, err := VoteOptionFromString(fields[0]) 108 if err != nil { 109 return options, err 110 } 111 if len(fields) < 2 { 112 return options, fmt.Errorf("weight field does not exist for %s option", fields[0]) 113 } 114 weight, err := sdk.NewDecFromStr(fields[1]) 115 if err != nil { 116 return options, err 117 } 118 options = append(options, WeightedVoteOption{option, weight}) 119 } 120 return options, nil 121 } 122 123 // ValidVoteOption returns true if the vote option is valid and false otherwise. 124 func ValidVoteOption(option VoteOption) bool { 125 if option == OptionYes || 126 option == OptionAbstain || 127 option == OptionNo || 128 option == OptionNoWithVeto { 129 return true 130 } 131 return false 132 } 133 134 // Marshal needed for protobuf compatibility. 135 func (vo VoteOption) Marshal() ([]byte, error) { 136 return []byte{byte(vo)}, nil 137 } 138 139 // Unmarshal needed for protobuf compatibility. 140 func (vo *VoteOption) Unmarshal(data []byte) error { 141 *vo = VoteOption(data[0]) 142 return nil 143 } 144 145 // Format implements the fmt.Formatter interface. 146 func (vo VoteOption) Format(s fmt.State, verb rune) { 147 var err error 148 149 switch verb { 150 case 's': 151 _, err = s.Write([]byte(vo.String())) 152 default: 153 _, err = s.Write([]byte(fmt.Sprintf("%v", byte(vo)))) 154 } 155 156 if err != nil { 157 panic(err) 158 } 159 }