github.com/Finschia/finschia-sdk@v0.48.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, _ := json.Marshal(v)
    66  	return string(out)
    67  }
    68  
    69  // WeightedVoteOptions describes array of WeightedVoteOptions
    70  type WeightedVoteOptions []WeightedVoteOption
    71  
    72  func (v WeightedVoteOptions) String() (out string) {
    73  	for _, opt := range v {
    74  		out += opt.String() + "\n"
    75  	}
    76  
    77  	return strings.TrimSpace(out)
    78  }
    79  
    80  // ValidWeightedVoteOption returns true if the sub vote is valid and false otherwise.
    81  func ValidWeightedVoteOption(option WeightedVoteOption) bool {
    82  	if !option.Weight.IsPositive() || option.Weight.GT(sdk.NewDec(1)) {
    83  		return false
    84  	}
    85  	return ValidVoteOption(option.Option)
    86  }
    87  
    88  // VoteOptionFromString returns a VoteOption from a string. It returns an error
    89  // if the string is invalid.
    90  func VoteOptionFromString(str string) (VoteOption, error) {
    91  	option, ok := VoteOption_value[str]
    92  	if !ok {
    93  		return OptionEmpty, fmt.Errorf("'%s' is not a valid vote option, available options: yes/no/no_with_veto/abstain", str)
    94  	}
    95  	return VoteOption(option), nil
    96  }
    97  
    98  // WeightedVoteOptionsFromString returns weighted vote options from string. It returns an error
    99  // if the string is invalid.
   100  func WeightedVoteOptionsFromString(str string) (WeightedVoteOptions, error) {
   101  	options := WeightedVoteOptions{}
   102  	for _, option := range strings.Split(str, ",") {
   103  		fields := strings.Split(option, "=")
   104  		option, err := VoteOptionFromString(fields[0])
   105  		if err != nil {
   106  			return options, err
   107  		}
   108  		if len(fields) < 2 {
   109  			return options, fmt.Errorf("weight field does not exist for %s option", fields[0])
   110  		}
   111  		weight, err := sdk.NewDecFromStr(fields[1])
   112  		if err != nil {
   113  			return options, err
   114  		}
   115  		options = append(options, WeightedVoteOption{option, weight})
   116  	}
   117  	return options, nil
   118  }
   119  
   120  // ValidVoteOption returns true if the vote option is valid and false otherwise.
   121  func ValidVoteOption(option VoteOption) bool {
   122  	if option == OptionYes ||
   123  		option == OptionAbstain ||
   124  		option == OptionNo ||
   125  		option == OptionNoWithVeto {
   126  		return true
   127  	}
   128  	return false
   129  }
   130  
   131  // Marshal needed for protobuf compatibility.
   132  func (vo VoteOption) Marshal() ([]byte, error) {
   133  	return []byte{byte(vo)}, nil
   134  }
   135  
   136  // Unmarshal needed for protobuf compatibility.
   137  func (vo *VoteOption) Unmarshal(data []byte) error {
   138  	*vo = VoteOption(data[0])
   139  	return nil
   140  }
   141  
   142  // Format implements the fmt.Formatter interface.
   143  func (vo VoteOption) Format(s fmt.State, verb rune) {
   144  	switch verb {
   145  	case 's':
   146  		s.Write([]byte(vo.String()))
   147  	default:
   148  		s.Write([]byte(fmt.Sprintf("%v", byte(vo))))
   149  	}
   150  }