func (status ProposalStatus) MarshalJSON() ([]byte, error) {
	return json.Marshal(status.String())
}
Marshals to JSON using string
package types
import (
	"encoding/json"
	"fmt"
	"strings"
	"time"
	sdk "github.com/Dipper-Labs/Dipper-Protocol/types"
)
type Proposal struct {
	Content `json:"content" yaml:"content"`  
	ProposalID       uint64         `json:"id" yaml:"id"`                                  
	Status           ProposalStatus `json:"proposal_status" 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   sdk.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"`      
	Proposer        sdk.AccAddress `json:"proposer"`
}
func NewProposal(content Content, id uint64, submitTime, depositEndTime time.Time, proposer sdk.AccAddress) Proposal {
	return Proposal{
		Content:          content,
		ProposalID:       id,
		Status:           StatusDepositPeriod,
		FinalTallyResult: EmptyTallyResult(),
		TotalDeposit:     sdk.NewCoins(),
		SubmitTime:       submitTime,
		DepositEndTime:   depositEndTime,
		Proposer:         proposer,
	}
}
func (p Proposal) String() string {
	return fmt.Sprintf(`Proposal %d:
  Title:              %s
  Type:               %s
  Status:             %s
  Submit Time:        %s
  Deposit End Time:   %s
  Total Deposit:      %s
  Voting Start Time:  %s
  Voting End Time:    %s
  Description:        %s
  Proposer:           %s`,
		p.ProposalID, p.GetTitle(), p.ProposalType(),
		p.Status, p.SubmitTime, p.DepositEndTime,
		p.TotalDeposit, p.VotingStartTime, p.VotingEndTime, p.GetDescription(), p.Proposer.String(),
	)
}
type Proposals []Proposal
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
	ProposalStatus byte
)
const (
	StatusNil           ProposalStatus = 0x00
	StatusDepositPeriod ProposalStatus = 0x01
	StatusVotingPeriod  ProposalStatus = 0x02
	StatusPassed        ProposalStatus = 0x03
	StatusRejected      ProposalStatus = 0x04
	StatusFailed        ProposalStatus = 0x05
)
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
}