Add message-{size|delay}-limit

This commit is contained in:
binwiederhier
2024-03-07 11:53:12 -05:00
parent 17709f2fb7
commit 36b33030f3
12 changed files with 210 additions and 90 deletions

View File

@@ -83,6 +83,22 @@ func ParseDuration(s string) (time.Duration, error) {
return 0, errUnparsableTime
}
func FormatDuration(d time.Duration) string {
if d >= 24*time.Hour {
return strconv.Itoa(int(d/(24*time.Hour))) + "d"
}
if d >= time.Hour {
return strconv.Itoa(int(d/time.Hour)) + "h"
}
if d >= time.Minute {
return strconv.Itoa(int(d/time.Minute)) + "m"
}
if d >= time.Second {
return strconv.Itoa(int(d/time.Second)) + "s"
}
return "0s"
}
func parseFromDuration(s string, now time.Time) (time.Time, error) {
d, err := ParseDuration(s)
if err == nil {

View File

@@ -92,3 +92,27 @@ func TestParseDuration(t *testing.T) {
require.Nil(t, err)
require.Equal(t, time.Duration(0), d)
}
func TestFormatDuration(t *testing.T) {
values := []struct {
duration time.Duration
expected string
}{
{24 * time.Second, "24s"},
{56 * time.Minute, "56m"},
{time.Hour, "1h"},
{2 * time.Hour, "2h"},
{24 * time.Hour, "1d"},
{3 * 24 * time.Hour, "3d"},
}
for _, value := range values {
require.Equal(t, value.expected, FormatDuration(value.duration))
d, err := ParseDuration(FormatDuration(value.duration))
require.Nil(t, err)
require.Equalf(t, value.duration, d, "duration does not match: %v != %v", value.duration, d)
}
}
func TestFormatDuration_Rounded(t *testing.T) {
require.Equal(t, "1d", FormatDuration(47*time.Hour))
}

View File

@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"io"
"math"
"math/rand"
"net/netip"
"os"
@@ -215,6 +216,8 @@ func ParseSize(s string) (int64, error) {
return -1, fmt.Errorf("cannot convert number %s", matches[1])
}
switch strings.ToUpper(matches[2]) {
case "T":
return int64(value) * 1024 * 1024 * 1024 * 1024, nil
case "G":
return int64(value) * 1024 * 1024 * 1024, nil
case "M":
@@ -226,8 +229,23 @@ func ParseSize(s string) (int64, error) {
}
}
// FormatSize formats bytes into a human-readable notation, e.g. 2.1 MB
// FormatSize formats the size in a way that it can be parsed by ParseSize.
// It does not include decimal places. Uneven sizes are rounded down.
func FormatSize(b int64) string {
const unit = 1024
if b < unit {
return fmt.Sprintf("%d", b)
}
div, exp := int64(unit), 0
for n := b / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%d%c", int(math.Floor(float64(b)/float64(div))), "KMGT"[exp])
}
// FormatSizeHuman formats bytes into a human-readable notation, e.g. 2.1 MB
func FormatSizeHuman(b int64) string {
const unit = 1024
if b < unit {
return fmt.Sprintf("%d bytes", b)
@@ -237,7 +255,7 @@ func FormatSize(b int64) string {
div *= unit
exp++
}
return fmt.Sprintf("%.1f %cB", float64(b)/float64(div), "KMGTPE"[exp])
return fmt.Sprintf("%.1f %cB", float64(b)/float64(div), "KMGT"[exp])
}
// ReadPassword will read a password from STDIN. If the terminal supports it, it will not print the

View File

@@ -110,33 +110,47 @@ func TestShortTopicURL(t *testing.T) {
func TestParseSize_10GSuccess(t *testing.T) {
s, err := ParseSize("10G")
if err != nil {
t.Fatal(err)
}
require.Nil(t, err)
require.Equal(t, int64(10*1024*1024*1024), s)
}
func TestParseSize_10MUpperCaseSuccess(t *testing.T) {
s, err := ParseSize("10M")
if err != nil {
t.Fatal(err)
}
require.Nil(t, err)
require.Equal(t, int64(10*1024*1024), s)
}
func TestParseSize_10kLowerCaseSuccess(t *testing.T) {
s, err := ParseSize("10k")
if err != nil {
t.Fatal(err)
}
require.Nil(t, err)
require.Equal(t, int64(10*1024), s)
}
func TestParseSize_FailureInvalid(t *testing.T) {
_, err := ParseSize("not a size")
if err == nil {
t.Fatalf("expected error, but got none")
require.Nil(t, err)
}
func TestFormatSize(t *testing.T) {
values := []struct {
size int64
expected string
}{
{10, "10"},
{10 * 1024, "10K"},
{10 * 1024 * 1024, "10M"},
{10 * 1024 * 1024 * 1024, "10G"},
}
for _, value := range values {
require.Equal(t, value.expected, FormatSize(value.size))
s, err := ParseSize(FormatSize(value.size))
require.Nil(t, err)
require.Equalf(t, value.size, s, "size does not match: %d != %d", value.size, s)
}
}
func TestFormatSize_Rounded(t *testing.T) {
require.Equal(t, "10K", FormatSize(10*1024+999))
}
func TestSplitKV(t *testing.T) {