func ProposalHandler(_ sdk.Context, c Content) error {
	switch c.ProposalType() {
	case ProposalTypeText:
		return nil
	default:
		return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized gov proposal type: %s", c.ProposalType())
	}
}
ProposalHandler implements the Handler interface for governance module-based
proposals (ie. TextProposal ). Since these are
merely signaling mechanisms at the moment and do not affect state, it
performs a no-op.
package types
import (
	"encoding/json"
	"fmt"
	"strings"
	"time"
	sdk "github.com/cosmos/cosmos-sdk/types"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
	"gopkg.in/yaml.v2"
)
const DefaultStartingProposalID uint64 = 1
type ProposalStatus int32
const (
	StatusNil ProposalStatus = 0
	StatusDepositPeriod ProposalStatus = 1
	StatusVotingPeriod ProposalStatus = 2
	StatusPassed ProposalStatus = 3
	StatusRejected ProposalStatus = 4
	StatusFailed ProposalStatus = 5
)
type ProposalBase struct {
	ProposalID       uint64         `json:"id" yaml:"id"`
	Status           ProposalStatus `json:"status,omitempty" yaml:"proposal_status"`
	FinalTallyResult TallyResult    `json:"final_tally_result" yaml:"final_tally_result"`
	SubmitTime       time.Time      `json:"submit_time" yaml:"submit_time"`
	DepositEndTime   time.Time      `json:"deposit_end_time" yaml:"deposit_end_time"`
	TotalDeposit     Coins          `json:"total_deposit" yaml:"total_deposit"`
	VotingStartTime  time.Time      `json:"voting_start_time" yaml:"voting_start_time"`
	VotingEndTime    time.Time      `json:"voting_end_time" yaml:"voting_end_time"`
}
func (p ProposalBase) Equal(other ProposalBase) bool {
	return p.ProposalID == other.ProposalID &&
		p.Status == other.Status &&
		p.FinalTallyResult.Equal(other.FinalTallyResult) &&
		p.SubmitTime.Equal(other.SubmitTime) &&
		p.DepositEndTime.Equal(other.DepositEndTime) &&
		p.TotalDeposit.IsEqual(other.TotalDeposit) &&
		p.VotingEndTime.Equal(other.VotingEndTime) &&
		p.VotingEndTime.Equal(other.VotingEndTime)
}
type Proposal struct {
	Content `json:"content" yaml:"content"`  
	ProposalBase
}
func NewProposal(content Content, id uint64, submitTime, depositEndTime time.Time) Proposal {
	return Proposal{
		Content: content,
		ProposalBase: ProposalBase{
			ProposalID:       id,
			Status:           StatusDepositPeriod,
			FinalTallyResult: EmptyTallyResult(),
			TotalDeposit:     NewCoins(),
			SubmitTime:       submitTime,
			DepositEndTime:   depositEndTime,
		},
	}
}
func (p Proposal) Equal(other Proposal) bool {
	return p.ProposalBase.Equal(other.ProposalBase) && p.Content.String() == other.Content.String()
}
func (p Proposal) String() string {
	out, _ := yaml.Marshal(p)
	return string(out)
}
type Proposals []Proposal
func (p Proposals) Equal(other Proposals) bool {
	if len(p) != len(other) {
		return false
	}
	for i, proposal := range p {
		if !proposal.Equal(other[i]) {
			return false
		}
	}
	return true
}
func (p Proposals) String() string {
	out := "ID - (Status) [Type] Title\n"
	for _, prop := range p {
		out += fmt.Sprintf("%d - (%s) [%s] %s\n",
			prop.ProposalID, prop.Status,
			prop.ProposalType(), prop.GetTitle())
	}
	return strings.TrimSpace(out)
}
type (
	ProposalQueue []uint64
)
func ProposalStatusFromString(str string) (ProposalStatus, error) {
	switch str {
	case "DepositPeriod":
		return StatusDepositPeriod, nil
	case "VotingPeriod":
		return StatusVotingPeriod, nil
	case "Passed":
		return StatusPassed, nil
	case "Rejected":
		return StatusRejected, nil
	case "Failed":
		return StatusFailed, nil
	case "":
		return StatusNil, nil
	default:
		return ProposalStatus(0xff), fmt.Errorf("'%s' is not a valid proposal status", str)
	}
}
func ValidProposalStatus(status ProposalStatus) bool {
	if status == StatusDepositPeriod ||
		status == StatusVotingPeriod ||
		status == StatusPassed ||
		status == StatusRejected ||
		status == StatusFailed {
		return true
	}
	return false
}
func (status ProposalStatus) Marshal() ([]byte, error) {
	return []byte{byte(status)}, nil
}
func (status *ProposalStatus) Unmarshal(data []byte) error {
	*status = ProposalStatus(data[0])
	return nil
}
func (status ProposalStatus) MarshalJSON() ([]byte, error) {
	return json.Marshal(status.String())
}
func (status *ProposalStatus) UnmarshalJSON(data []byte) error {
	var s string
	err := json.Unmarshal(data, &s)
	if err != nil {
		return err
	}
	bz2, err := ProposalStatusFromString(s)
	if err != nil {
		return err
	}
	*status = bz2
	return nil
}
func (status ProposalStatus) String() string {
	switch status {
	case StatusDepositPeriod:
		return "DepositPeriod"
	case StatusVotingPeriod:
		return "VotingPeriod"
	case StatusPassed:
		return "Passed"
	case StatusRejected:
		return "Rejected"
	case StatusFailed:
		return "Failed"
	default:
		return ""
	}
}
func (status ProposalStatus) Format(s fmt.State, verb rune) {
	switch verb {
	case 's':
		s.Write([]byte(status.String()))
	default:
		s.Write([]byte(fmt.Sprintf("%v", byte(status))))
	}
}
const (
	ProposalTypeText string = "Text"
)
var _ Content = TextProposal{}
type TextProposal struct {
	Title       string `json:"title,omitempty" yaml:"title"`
	Description string `json:"description,omitempty" yaml:"description"`
}
func NewTextProposal(title, description string) Content {
	return TextProposal{title, description}
}
func (tp TextProposal) GetTitle() string { return tp.Title }
func (tp TextProposal) GetDescription() string { return tp.Description }
func (tp TextProposal) ProposalRoute() string { return RouterKey }
func (tp TextProposal) ProposalType() string { return ProposalTypeText }
func (tp TextProposal) ValidateBasic() error { return ValidateAbstract(tp) }
func (tp TextProposal) String() string {
	out, _ := yaml.Marshal(tp)
	return string(out)
}
var validProposalTypes = map[string]struct{}{
	ProposalTypeText: {},
}
func RegisterProposalType(ty string) {
	if _, ok := validProposalTypes[ty]; ok {
		panic(fmt.Sprintf("already registered proposal type: %s", ty))
	}
	validProposalTypes[ty] = struct{}{}
}
func ContentFromProposalType(title, desc, ty string) Content {
	switch ty {
	case ProposalTypeText:
		return NewTextProposal(title, desc)
	default:
		return nil
	}
}
func IsValidProposalType(ty string) bool {
	_, ok := validProposalTypes[ty]
	return ok
}