blob: a392605a28fbdb394782befde55c41711dd0acd7 [file] [log] [blame]
Abhay Kumara61c5222025-11-10 07:32:50 +00001package pb
2
3import (
4 "bytes"
5 "fmt"
6 "github.com/mattn/go-runewidth"
7 "math"
8 "regexp"
9 //"unicode/utf8"
10)
11
12const (
13 _KiB = 1024
14 _MiB = 1048576
15 _GiB = 1073741824
16 _TiB = 1099511627776
17
18 _kB = 1e3
19 _MB = 1e6
20 _GB = 1e9
21 _TB = 1e12
22)
23
24var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9;]+\x6d")
25
26func CellCount(s string) int {
27 n := runewidth.StringWidth(s)
28 for _, sm := range ctrlFinder.FindAllString(s, -1) {
29 n -= runewidth.StringWidth(sm)
30 }
31 return n
32}
33
34func StripString(s string, w int) string {
35 l := CellCount(s)
36 if l <= w {
37 return s
38 }
39 var buf = bytes.NewBuffer(make([]byte, 0, len(s)))
40 StripStringToBuffer(s, w, buf)
41 return buf.String()
42}
43
44func StripStringToBuffer(s string, w int, buf *bytes.Buffer) {
45 var seqs = ctrlFinder.FindAllStringIndex(s, -1)
46 var maxWidthReached bool
47mainloop:
48 for i, r := range s {
49 for _, seq := range seqs {
50 if i >= seq[0] && i < seq[1] {
51 buf.WriteRune(r)
52 continue mainloop
53 }
54 }
55 if rw := CellCount(string(r)); rw <= w && !maxWidthReached {
56 w -= rw
57 buf.WriteRune(r)
58 } else {
59 maxWidthReached = true
60 }
61 }
62 for w > 0 {
63 buf.WriteByte(' ')
64 w--
65 }
66 return
67}
68
69func round(val float64) (newVal float64) {
70 roundOn := 0.5
71 places := 0
72 var round float64
73 pow := math.Pow(10, float64(places))
74 digit := pow * val
75 _, div := math.Modf(digit)
76 if div >= roundOn {
77 round = math.Ceil(digit)
78 } else {
79 round = math.Floor(digit)
80 }
81 newVal = round / pow
82 return
83}
84
85// Convert bytes to human readable string. Like a 2 MiB, 64.2 KiB, or 2 MB, 64.2 kB
86// if useSIPrefix is set to true
87func formatBytes(i int64, useSIPrefix bool) (result string) {
88 if !useSIPrefix {
89 switch {
90 case i >= _TiB:
91 result = fmt.Sprintf("%.02f TiB", float64(i)/_TiB)
92 case i >= _GiB:
93 result = fmt.Sprintf("%.02f GiB", float64(i)/_GiB)
94 case i >= _MiB:
95 result = fmt.Sprintf("%.02f MiB", float64(i)/_MiB)
96 case i >= _KiB:
97 result = fmt.Sprintf("%.02f KiB", float64(i)/_KiB)
98 default:
99 result = fmt.Sprintf("%d B", i)
100 }
101 } else {
102 switch {
103 case i >= _TB:
104 result = fmt.Sprintf("%.02f TB", float64(i)/_TB)
105 case i >= _GB:
106 result = fmt.Sprintf("%.02f GB", float64(i)/_GB)
107 case i >= _MB:
108 result = fmt.Sprintf("%.02f MB", float64(i)/_MB)
109 case i >= _kB:
110 result = fmt.Sprintf("%.02f kB", float64(i)/_kB)
111 default:
112 result = fmt.Sprintf("%d B", i)
113 }
114 }
115 return
116}