mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
Merge branch 'WTF-897-exchange-rate-alignment'
This commit is contained in:
commit
510c5d576c
@ -15,6 +15,8 @@ const (
|
||||
type Settings struct {
|
||||
common *cfg.Common
|
||||
|
||||
precision int `help:"How many decimal places to display." optional:"true"`
|
||||
|
||||
rates map[string][]string `help:"Defines what currency rates we want to know about"`
|
||||
order []string
|
||||
}
|
||||
@ -24,6 +26,8 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
|
||||
settings := Settings{
|
||||
common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
|
||||
|
||||
precision: ymlConfig.UInt("precision", 7),
|
||||
|
||||
rates: map[string][]string{},
|
||||
order: []string{},
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
// Package exchangerates
|
||||
package exchangerates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/view"
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
)
|
||||
|
||||
type Widget struct {
|
||||
@ -50,22 +51,38 @@ func (widget *Widget) Render() {
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) content() (string, string, bool) {
|
||||
out := ""
|
||||
|
||||
if widget.err != nil {
|
||||
out = widget.err.Error()
|
||||
} else {
|
||||
for base, rates := range widget.settings.rates {
|
||||
prefix := fmt.Sprintf("[%s]1 %s[white] = ", widget.settings.common.Colors.Subheading, base)
|
||||
widget.View.SetWrap(true)
|
||||
return widget.CommonSettings().Title, widget.err.Error(), false
|
||||
}
|
||||
|
||||
for idx, cur := range rates {
|
||||
rate := widget.rates[base][cur]
|
||||
out := ""
|
||||
idx := 0
|
||||
for base, rates := range widget.settings.rates {
|
||||
for _, cur := range rates {
|
||||
rate := widget.rates[base][cur]
|
||||
|
||||
out += prefix
|
||||
out += fmt.Sprintf("[%s]%f %s[white]\n", widget.CommonSettings().RowColor(idx), rate, cur)
|
||||
}
|
||||
out += fmt.Sprintf(
|
||||
"[%s]1 %s = %s %s[white]\n",
|
||||
widget.CommonSettings().RowColor(idx),
|
||||
base,
|
||||
widget.formatConversionRate(rate),
|
||||
cur,
|
||||
)
|
||||
|
||||
idx++
|
||||
}
|
||||
}
|
||||
|
||||
widget.View.SetWrap(false)
|
||||
return widget.CommonSettings().Title, out, false
|
||||
}
|
||||
|
||||
// formatConversionRate takes the raw conversion float and formats it to the precision the
|
||||
// user specifies in their config (or to the default value)
|
||||
func (widget *Widget) formatConversionRate(rate float64) string {
|
||||
rate = wtf.TruncateFloat64(rate, widget.settings.precision)
|
||||
|
||||
r, _ := regexp.Compile(`\.?0*$`)
|
||||
return r.ReplaceAllString(fmt.Sprintf("%10.7f", rate), "")
|
||||
}
|
||||
|
14
wtf/numbers.go
Normal file
14
wtf/numbers.go
Normal file
@ -0,0 +1,14 @@
|
||||
package wtf
|
||||
|
||||
import "math"
|
||||
|
||||
// Round rounds a float to an integer
|
||||
func Round(num float64) int {
|
||||
return int(num + math.Copysign(0.5, num))
|
||||
}
|
||||
|
||||
// TruncateFloat64 truncates the decimal places of a float64 to the specified precision
|
||||
func TruncateFloat64(num float64, precision int) float64 {
|
||||
output := math.Pow(10, float64(precision))
|
||||
return float64(Round(num*output)) / output
|
||||
}
|
78
wtf/numbers_test.go
Normal file
78
wtf/numbers_test.go
Normal file
@ -0,0 +1,78 @@
|
||||
package wtf
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
||||
func Test_Round(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input float64
|
||||
expected int
|
||||
}{
|
||||
{
|
||||
name: "negative",
|
||||
input: -3,
|
||||
expected: -3,
|
||||
},
|
||||
{
|
||||
name: "integer",
|
||||
input: 3,
|
||||
expected: 3,
|
||||
},
|
||||
{
|
||||
name: "float down",
|
||||
input: 3.123456,
|
||||
expected: 3,
|
||||
},
|
||||
{
|
||||
name: "float up",
|
||||
input: 3.998786,
|
||||
expected: 4,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual := Round(tt.input)
|
||||
assert.Equal(t, tt.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_TruncateFloat(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input float64
|
||||
precision int
|
||||
expected float64
|
||||
}{
|
||||
{
|
||||
name: "negative precision",
|
||||
input: 23.234567,
|
||||
precision: -2,
|
||||
expected: 0,
|
||||
},
|
||||
{
|
||||
name: "zero precision",
|
||||
input: 23.234567,
|
||||
precision: 0,
|
||||
expected: 23,
|
||||
},
|
||||
{
|
||||
name: "positive precision",
|
||||
input: 23.234567,
|
||||
precision: 2,
|
||||
expected: 23.23,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual := TruncateFloat64(tt.input, tt.precision)
|
||||
assert.Equal(t, tt.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user