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  }