79 lines
2.2 KiB
Go
79 lines
2.2 KiB
Go
package binancerecharge
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
func parsePositiveDecimal(value string, field string) (*big.Rat, string, error) {
|
|
normalized, err := normalizeDecimal(value)
|
|
if err != nil {
|
|
return nil, "", NewAppError(http.StatusBadRequest, "invalid_"+field, field+" must be a decimal number")
|
|
}
|
|
rat, ok := new(big.Rat).SetString(normalized)
|
|
if !ok || rat.Sign() <= 0 {
|
|
return nil, "", NewAppError(http.StatusBadRequest, "invalid_"+field, field+" must be greater than 0")
|
|
}
|
|
return rat, normalized, nil
|
|
}
|
|
|
|
func parseNonNegativeDecimal(value string, field string) (*big.Rat, string, error) {
|
|
normalized, err := normalizeDecimal(value)
|
|
if err != nil {
|
|
return nil, "", NewAppError(http.StatusBadRequest, "invalid_"+field, field+" must be a decimal number")
|
|
}
|
|
rat, ok := new(big.Rat).SetString(normalized)
|
|
if !ok || rat.Sign() < 0 {
|
|
return nil, "", NewAppError(http.StatusBadRequest, "invalid_"+field, field+" must be greater than or equal to 0")
|
|
}
|
|
return rat, normalized, nil
|
|
}
|
|
|
|
func normalizeDecimal(value string) (string, error) {
|
|
value = strings.TrimSpace(value)
|
|
if value == "" {
|
|
return "", fmt.Errorf("blank decimal")
|
|
}
|
|
rat, ok := new(big.Rat).SetString(value)
|
|
if !ok {
|
|
return "", fmt.Errorf("invalid decimal")
|
|
}
|
|
return trimDecimalZeros(rat.FloatString(8)), nil
|
|
}
|
|
|
|
func trimDecimalZeros(value string) string {
|
|
value = strings.TrimSpace(value)
|
|
if !strings.Contains(value, ".") {
|
|
return value
|
|
}
|
|
value = strings.TrimRight(value, "0")
|
|
value = strings.TrimRight(value, ".")
|
|
if value == "" || value == "-0" {
|
|
return "0"
|
|
}
|
|
return value
|
|
}
|
|
|
|
func decimalEqual(left string, right string) bool {
|
|
leftRat, ok := new(big.Rat).SetString(strings.TrimSpace(left))
|
|
if !ok {
|
|
return false
|
|
}
|
|
rightRat, ok := new(big.Rat).SetString(strings.TrimSpace(right))
|
|
if !ok {
|
|
return false
|
|
}
|
|
return leftRat.Cmp(rightRat) == 0
|
|
}
|
|
|
|
func calculateGold(amount *big.Rat, rate *big.Rat) (int64, error) {
|
|
product := new(big.Rat).Mul(amount, rate)
|
|
gold := new(big.Int).Quo(product.Num(), product.Denom())
|
|
if !gold.IsInt64() {
|
|
return 0, NewAppError(http.StatusBadRequest, "gold_amount_too_large", "gold amount is too large")
|
|
}
|
|
return gold.Int64(), nil
|
|
}
|