diff --git a/formatter/formatter.go b/formatter/formatter.go index eb56dd3..be76085 100644 --- a/formatter/formatter.go +++ b/formatter/formatter.go @@ -4,14 +4,25 @@ // Package formatter implements some functions to format string, struct. package formatter -import "strings" +import ( + "strings" + + "golang.org/x/exp/constraints" +) + +// Comma add comma to a number value by every 3 numbers from right. ahead by symbol char. +// if value is invalid number string eg "aa", return empty string +// Comma("12345", "$") => "$12,345", Comma(12345, "$") => "$12,345" +func Comma[T constraints.Float | constraints.Integer | string](value T, symbol string) string { + s, err := numberToString(value) + if err != nil { + return "" + } -// Comma add comma to number by every 3 numbers from right. ahead by symbol char -func Comma(v any, symbol string) string { - s := numString(v) dotIndex := strings.Index(s, ".") if dotIndex != -1 { return symbol + commaString(s[:dotIndex]) + s[dotIndex:] } + return symbol + commaString(s) } diff --git a/formatter/formatter_internal.go b/formatter/formatter_internal.go index 7d698a9..55be4aa 100644 --- a/formatter/formatter_internal.go +++ b/formatter/formatter_internal.go @@ -14,27 +14,34 @@ func commaString(s string) string { return commaString(s[:len(s)-3]) + "," + commaString(s[len(s)-3:]) } -func numString(value any) string { +func numberToString(value any) (string, error) { switch reflect.TypeOf(value).Kind() { - case reflect.Int, reflect.Int64, reflect.Float32, reflect.Float64: - return fmt.Sprintf("%v", value) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return fmt.Sprintf("%v", value), nil + + // todo: need to handle 12345678.9 => 1.23456789e+07 + case reflect.Float32, reflect.Float64: + return fmt.Sprintf("%v", value), nil + case reflect.String: { sv := fmt.Sprintf("%v", value) if strings.Contains(sv, ".") { _, err := strconv.ParseFloat(sv, 64) - if err == nil { - return sv + if err != nil { + return "", err } + return sv, nil } else { _, err := strconv.ParseInt(sv, 10, 64) - if err == nil { - return sv + if err != nil { + return "", nil } + return sv, nil } } default: - return "" + return "", nil } - return "" } diff --git a/formatter/formatter_test.go b/formatter/formatter_test.go index 6f57c23..b198620 100644 --- a/formatter/formatter_test.go +++ b/formatter/formatter_test.go @@ -12,12 +12,16 @@ func TestComma(t *testing.T) { assert.Equal("", Comma("", "")) assert.Equal("", Comma("aa", "")) assert.Equal("", Comma("aa.a", "")) - assert.Equal("", Comma([]int{1}, "")) assert.Equal("123", Comma("123", "")) assert.Equal("12,345", Comma("12345", "")) + assert.Equal("12,345.6789", Comma("12345.6789", "")) + assert.Equal("123,456,789,000", Comma("123456789000", "")) assert.Equal("12,345", Comma(12345, "")) assert.Equal("$12,345", Comma(12345, "$")) assert.Equal("¥12,345", Comma(12345, "¥")) assert.Equal("12,345.6789", Comma(12345.6789, "")) + assert.Equal("12,345.6789", Comma(+12345.6789, "")) + assert.Equal("12,345,678.9", Comma(12345678.9, "")) + assert.Equal("123,456,789,000", Comma(123456789000, "")) } diff --git a/go.mod b/go.mod index 3377344..9e6c3ae 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module github.com/duke-git/lancet/v2 go 1.18 -require golang.org/x/text v0.5.0 +require ( + golang.org/x/exp v0.0.0-20221208152030-732eee02a75a + golang.org/x/text v0.5.0 +) diff --git a/go.sum b/go.sum index a0726a8..a12ea5d 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ +golang.org/x/exp v0.0.0-20221208152030-732eee02a75a h1:4iLhBPcpqFmylhnkbY3W0ONLUYYkDAW9xMFLfxgsvCw= +golang.org/x/exp v0.0.0-20221208152030-732eee02a75a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=