cosmos-sdk/x/distribution/types/dec_coin.go

104 lines
2.3 KiB
Go

package types
import (
"strings"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Coins which can have additional decimal points
type DecCoin struct {
Denom string `json:"denom"`
Amount sdk.Dec `json:"amount"`
}
func NewDecCoin(coin sdk.Coin) DecCoin {
return DecCoin{
Denom: coin.Denom,
Amount: sdk.NewDecFromInt(coin.Amount),
}
}
// Adds amounts of two coins with same denom
func (coin DecCoin) Plus(coinB DecCoin) DecCoin {
if !(coin.Denom == coinB.Denom) {
return coin
}
return DecCoin{coin.Denom, coin.Amount.Add(coinB.Amount)}
}
// return the decimal coins with trunctated decimals
func (coin DecCoin) TruncateDecimal() sdk.Coin {
return sdk.NewCoin(coin.Denom, coin.Amount.TruncateInt())
}
//_______________________________________________________________________
// coins with decimal
type DecCoins []DecCoin
func NewDecCoins(coins sdk.Coins) DecCoins {
dcs := make(DecCoins, len(coins))
for i, coin := range coins {
dcs[i] = NewDecCoin(coin)
}
return dcs
}
// return the coins with trunctated decimals
func (coins DecCoins) TruncateDecimal() sdk.Coins {
out := make(sdk.Coins, len(coins))
for i, coin := range coins {
out[i] = coin.TruncateDecimal()
}
return out
}
// Plus combines two sets of coins
// CONTRACT: Plus will never return Coins where one Coin has a 0 amount.
func (coins DecCoins) Plus(coinsB DecCoins) DecCoins {
sum := ([]DecCoin)(nil)
indexA, indexB := 0, 0
lenA, lenB := len(coins), len(coinsB)
for {
if indexA == lenA {
if indexB == lenB {
return sum
}
return append(sum, coinsB[indexB:]...)
} else if indexB == lenB {
return append(sum, coins[indexA:]...)
}
coinA, coinB := coins[indexA], coinsB[indexB]
switch strings.Compare(coinA.Denom, coinB.Denom) {
case -1:
sum = append(sum, coinA)
indexA++
case 0:
if coinA.Amount.Add(coinB.Amount).IsZero() {
// ignore 0 sum coin type
} else {
sum = append(sum, coinA.Plus(coinB))
}
indexA++
indexB++
case 1:
sum = append(sum, coinB)
indexB++
}
}
}
// multiply all the coins by a multiple
func (coins DecCoins) Mul(multiple sdk.Dec) DecCoins {
products := make([]DecCoin, len(coins))
for i, coin := range coins {
product := DecCoin{
Denom: coin.Denom,
Amount: coin.Amount.Mul(multiple),
}
products[i] = product
}
return products
}