Skip to content

Commit

Permalink
👔 up(fmt,math): move commonly util func to pkg basefn
Browse files Browse the repository at this point in the history
- func DataSize, HowLongAgo
  • Loading branch information
inhere committed Mar 16, 2023
1 parent 53f7769 commit 5221781
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 60 deletions.
72 changes: 72 additions & 0 deletions basefn/extfunc.go
@@ -0,0 +1,72 @@
package basefn

import "fmt"

// DataSize format bytes number friendly.
//
// Usage:
//
// file, err := os.Open(path)
// fl, err := file.Stat()
// fmtSize := DataSize(fl.Size())
func DataSize(size uint64) string {
switch {
case size < 1024:
return fmt.Sprintf("%dB", size)
case size < 1024*1024:
return fmt.Sprintf("%.2fK", float64(size)/1024)
case size < 1024*1024*1024:
return fmt.Sprintf("%.2fM", float64(size)/1024/1024)
default:
return fmt.Sprintf("%.2fG", float64(size)/1024/1024/1024)
}
}

var timeFormats = [][]int{
{0},
{1},
{2, 1},
{60},
{120, 60},
{3600},
{7200, 3600},
{86400},
{172800, 86400},
}

var timeMessages = []string{
"< 1 sec", "1 sec", "secs", "1 min", "mins", "1 hr", "hrs", "1 day", "days",
}

// HowLongAgo format a seconds, get how lang ago
func HowLongAgo(sec int64) string {
intVal := int(sec)
length := len(timeFormats)

for i, item := range timeFormats {
if intVal >= item[0] {
ni := i + 1
match := false

if ni < length { // next exists
next := timeFormats[ni]
if intVal < next[0] { // current <= intVal < next
match = true
}
} else if ni == length { // current is last
match = true
}

if match { // match success
if len(item) == 1 {
return timeMessages[i]
}

// len is 2
return fmt.Sprintf("%d %s", intVal/item[1], timeMessages[i])
}
}
}

return "unknown" // He should never happen
}
43 changes: 43 additions & 0 deletions basefn/extfunc_test.go
@@ -0,0 +1,43 @@
package basefn_test

import (
"testing"

"github.com/gookit/goutil/basefn"
"github.com/gookit/goutil/testutil/assert"
)

func TestDataSize(t *testing.T) {
tests := []struct {
args uint64
want string
}{
{346, "346B"},
{3467, "3.39K"},
{346778, "338.65K"},
{12346778, "11.77M"},
{1200346778, "1.12G"},
}

for _, tt := range tests {
assert.Eq(t, tt.want, basefn.DataSize(tt.args))
}
}

func TestHowLongAgo(t *testing.T) {
tests := []struct {
args int64
want string
}{
{-36, "unknown"},
{36, "36 secs"},
{346, "5 mins"},
{3467, "57 mins"},
{346778, "4 days"},
{1200346778, "13892 days"},
}

for _, tt := range tests {
assert.Eq(t, tt.want, basefn.HowLongAgo(tt.args))
}
}
15 changes: 15 additions & 0 deletions fmtutil/fmtutil.go
@@ -1,2 +1,17 @@
// Package fmtutil provide some format util functions.
package fmtutil

import (
"encoding/json"

"github.com/gookit/goutil/strutil"
)

// StringOrJSON encode pretty JSON data to json bytes.
func StringOrJSON(v any) ([]byte, error) {
s, err := strutil.StringOrErr(v)
if err != nil {
return json.MarshalIndent(v, "", " ")
}
return []byte(s), nil
}
13 changes: 3 additions & 10 deletions fmtutil/format.go
Expand Up @@ -6,6 +6,8 @@ import (
"strconv"
"strings"
"unicode"

"github.com/gookit/goutil/basefn"
)

// data size
Expand All @@ -23,16 +25,7 @@ const (
// fl, err := file.Stat()
// fmtSize := DataSize(fl.Size())
func DataSize(size uint64) string {
switch {
case size < 1024:
return fmt.Sprintf("%dB", size)
case size < 1024*1024:
return fmt.Sprintf("%.2fK", float64(size)/1024)
case size < 1024*1024*1024:
return fmt.Sprintf("%.2fM", float64(size)/1024/1024)
default:
return fmt.Sprintf("%.2fG", float64(size)/1024/1024/1024)
}
return basefn.DataSize(size)
}

// SizeToString alias of the DataSize
Expand Down
50 changes: 4 additions & 46 deletions fmtutil/time.go
@@ -1,52 +1,10 @@
package fmtutil

import "fmt"

var timeFormats = [][]int{
{0},
{1},
{2, 1},
{60},
{120, 60},
{3600},
{7200, 3600},
{86400},
{172800, 86400},
}

var timeMessages = []string{
"< 1 sec", "1 sec", "secs", "1 min", "mins", "1 hr", "hrs", "1 day", "days",
}
import (
"github.com/gookit/goutil/basefn"
)

// HowLongAgo format a seconds, get how lang ago
func HowLongAgo(sec int64) string {
intVal := int(sec)
length := len(timeFormats)

for i, item := range timeFormats {
if intVal >= item[0] {
ni := i + 1
match := false

if ni < length { // next exists
next := timeFormats[ni]
if intVal < next[0] { // current <= intVal < next
match = true
}
} else if ni == length { // current is last
match = true
}

if match { // match success
if len(item) == 1 {
return timeMessages[i]
}

// len is 2
return fmt.Sprintf("%d %s", intVal/item[1], timeMessages[i])
}
}
}

return "unknown" // He should never happen
return basefn.HowLongAgo(sec)
}
7 changes: 3 additions & 4 deletions mathutil/number.go
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"
"time"

"github.com/gookit/goutil/fmtutil"
"github.com/gookit/goutil/basefn"
)

// IsNumeric returns true if the given character is a numeric, otherwise false.
Expand All @@ -17,7 +17,6 @@ func Percent(val, total int) float64 {
if total == 0 {
return float64(0)
}

return (float64(val) / float64(total)) * 100
}

Expand All @@ -28,10 +27,10 @@ func ElapsedTime(startTime time.Time) string {

// DataSize format value. alias format.DataSize()
func DataSize(size uint64) string {
return fmtutil.DataSize(size)
return basefn.DataSize(size)
}

// HowLongAgo calc time. alias format.HowLongAgo()
func HowLongAgo(sec int64) string {
return fmtutil.HowLongAgo(sec)
return basefn.HowLongAgo(sec)
}

0 comments on commit 5221781

Please sign in to comment.