digits-2023-10-15/digits-work-sample-go-bree-.../amount.go

73 lines
1.8 KiB
Go

package analyzer
import (
"math"
"os"
"regexp"
"strings"
"golang.org/x/text/currency"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
type Amount float64
var localizedLanguagePrinter = func() *message.Printer {
_newLocalizedLanguage := func() (language.Tag, bool) {
environmentLang := os.Getenv("LANG")
if environmentLang == "" {
return language.Tag{}, false
}
regexp := regexp.MustCompile(`^([a-z]+)_([A-Z]+)\.[A-Z0-9-]+$`)
results := regexp.FindAllStringSubmatch(environmentLang, -1)
if len(results) != 1 || len(results[0]) != 3 {
return language.Tag{}, false
}
base, err := language.ParseBase(results[0][1])
if err != nil {
return language.Tag{}, false
}
region, err := language.ParseRegion(results[0][2])
if err != nil {
return language.Tag{}, false
}
result, err := language.Compose(base, region)
return result, err == nil
}
result, ok := _newLocalizedLanguage()
if !ok {
return message.NewPrinter(language.AmericanEnglish)
}
return message.NewPrinter(result)
}()
func (amount Amount) AbsoluteValue() Amount {
if amount < 0 {
return -1.0 * amount
}
return amount
}
// Rounded rounds a float to the number of places specified.
func (amount Amount) Rounded(places int) Amount {
p := math.Pow10(places)
return Amount(math.Round(float64(amount)*p) / p)
}
// FormatUSD formats Amount as a string in US dollars.
func (amount Amount) FormatUSD() string {
rounded := amount.Rounded(2)
prefix := ""
if rounded < 0 {
prefix = "-"
rounded *= -1.0
}
roundedAsCurrency := currency.NarrowSymbol(currency.USD.Amount(float32(rounded)))
resultWithSpaceAfterDollarSign := localizedLanguagePrinter.Sprintf("%s%.2f", prefix, roundedAsCurrency)
return strings.Replace(resultWithSpaceAfterDollarSign, "$ ", "$", 1)
}