k9s/internal/ui/deltas.go

143 lines
2.1 KiB
Go

package ui
import (
"regexp"
"strconv"
"strings"
"time"
"github.com/derailed/k9s/internal/render"
"k8s.io/apimachinery/pkg/api/resource"
)
const (
// DeltaSign signals a diff.
DeltaSign = "Δ"
// PlusSign signals inc.
PlusSign = "[red::b]↑"
// MinusSign signal dec.
MinusSign = "[green::b]↓"
)
var percent = regexp.MustCompile(`\A(\d+)\%\z`)
func deltaNumb(o, n string) (string, bool) {
var delta string
i, ok := numerical(o)
if !ok {
return delta, ok
}
j, _ := numerical(n)
switch {
case i < j:
delta = PlusSign
case i > j:
delta = MinusSign
}
return delta, ok
}
func deltaPerc(o, n string) (string, bool) {
var delta string
i, ok := percentage(o)
if !ok {
return delta, ok
}
j, _ := percentage(n)
switch {
case i < j:
delta = PlusSign
case i > j:
delta = MinusSign
}
return delta, ok
}
func deltaQty(o, n string) (string, bool) {
var delta string
q1, err := resource.ParseQuantity(o)
if err != nil {
return delta, false
}
q2, _ := resource.ParseQuantity(n)
switch q1.Cmp(q2) {
case -1:
delta = PlusSign
case 1:
delta = MinusSign
}
return delta, true
}
func deltaDur(o, n string) (string, bool) {
var delta string
d1, err := time.ParseDuration(o)
if err != nil {
return delta, false
}
d2, _ := time.ParseDuration(n)
switch {
case d2-d1 > 0:
delta = PlusSign
case d2-d1 < 0:
delta = MinusSign
}
return delta, true
}
// Deltas signals diffs between 2 strings.
func Deltas(o, n string) string {
o, n = strings.TrimSpace(o), strings.TrimSpace(n)
if o == "" || o == render.NAValue {
return ""
}
if d, ok := deltaNumb(o, n); ok {
return d
}
if d, ok := deltaPerc(o, n); ok {
return d
}
if d, ok := deltaQty(o, n); ok {
return d
}
if d, ok := deltaDur(o, n); ok {
return d
}
switch strings.Compare(o, n) {
case 1, -1:
return DeltaSign
default:
return ""
}
}
func percentage(s string) (int, bool) {
if res := percent.FindStringSubmatch(s); len(res) == 2 {
n, _ := strconv.Atoi(res[1])
return n, true
}
return 0, false
}
func numerical(s string) (int, bool) {
n, err := strconv.Atoi(s)
if err != nil {
return 0, false
}
return n, true
}