From be30f845001e9222a205fee3c065fb935cdde1b4 Mon Sep 17 00:00:00 2001 From: andeya Date: Tue, 20 Sep 2022 17:35:58 +0800 Subject: [PATCH] refactor(digit): move Digit to gust root path --- digit/digit.go => digit.go | 2 +- digit/atoi62.go | 18 +++++-- digit/atoi62_test.go | 80 ++++++++++++++++---------------- digit/converts.go | 78 ++++++++++++++++++------------- digit/dict_num.go | 10 ++-- digit/dict_num_test.go | 14 +++--- digit/utils.go | 12 ++--- examples/iterator/reduce_test.go | 3 +- iter/export.go | 5 +- iter/iterable_range.go | 5 +- ord/ordering.go => ordering.go | 6 +-- 11 files changed, 127 insertions(+), 106 deletions(-) rename digit/digit.go => digit.go (95%) rename ord/ordering.go => ordering.go (87%) diff --git a/digit/digit.go b/digit.go similarity index 95% rename from digit/digit.go rename to digit.go index ac87877..1504db7 100644 --- a/digit/digit.go +++ b/digit.go @@ -1,4 +1,4 @@ -package digit +package gust type PureInteger interface { int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 diff --git a/digit/atoi62.go b/digit/atoi62.go index 2423277..46b972b 100644 --- a/digit/atoi62.go +++ b/digit/atoi62.go @@ -4,13 +4,19 @@ import ( "errors" "math" "strconv" + + "github.com/andeya/gust" ) // ParseUint is like ParseInt but for unsigned numbers. // NOTE: // // Compatible with standard package strconv. -func ParseUint(s string, base int, bitSize int) (uint64, error) { +func ParseUint(s string, base int, bitSize int) gust.Result[uint64] { + return gust.Ret(parseUint(s, base, bitSize)) +} + +func parseUint(s string, base int, bitSize int) (uint64, error) { // Ignore letter case if base <= 36 { return strconv.ParseUint(s, base, bitSize) @@ -99,7 +105,11 @@ func ParseUint(s string, base int, bitSize int) (uint64, error) { // NOTE: // // Compatible with standard package strconv. -func ParseInt(s string, base int, bitSize int) (i int64, err error) { +func ParseInt(s string, base int, bitSize int) gust.Result[int64] { + return gust.Ret(parseInt(s, base, bitSize)) +} + +func parseInt(s string, base int, bitSize int) (i int64, err error) { // Ignore letter case if base <= 36 { return strconv.ParseInt(s, base, bitSize) @@ -123,7 +133,7 @@ func ParseInt(s string, base int, bitSize int) (i int64, err error) { // Convert unsigned and check range. var un uint64 - un, err = ParseUint(s, base, bitSize) + un, err = parseUint(s, base, bitSize) if err != nil && err.(*strconv.NumError).Err != strconv.ErrRange { err.(*strconv.NumError).Func = fnParseInt err.(*strconv.NumError).Num = s0 @@ -223,7 +233,7 @@ func Atoi(s string) (int, error) { } // Slow path for invalid, big, or underscored integers. - i64, err := ParseInt(s, 10, 0) + i64, err := parseInt(s, 10, 0) if nerr, ok := err.(*strconv.NumError); ok { nerr.Func = fnAtoi } diff --git a/digit/atoi62_test.go b/digit/atoi62_test.go index 6a5e888..9028de9 100644 --- a/digit/atoi62_test.go +++ b/digit/atoi62_test.go @@ -312,37 +312,37 @@ func init() { for i := range parseUint64Tests { test := &parseUint64Tests[i] if test.err != nil { - test.err = &strconv.NumError{"ParseUint", test.in, test.err} + test.err = &strconv.NumError{Func: "ParseUint", Num: test.in, Err: test.err} } } for i := range parseUint64BaseTests { test := &parseUint64BaseTests[i] if test.err != nil { - test.err = &strconv.NumError{"ParseUint", test.in, test.err} + test.err = &strconv.NumError{Func: "ParseUint", Num: test.in, Err: test.err} } } for i := range parseInt64Tests { test := &parseInt64Tests[i] if test.err != nil { - test.err = &strconv.NumError{"ParseInt", test.in, test.err} + test.err = &strconv.NumError{Func: "ParseInt", Num: test.in, Err: test.err} } } for i := range parseInt64BaseTests { test := &parseInt64BaseTests[i] if test.err != nil { - test.err = &strconv.NumError{"ParseInt", test.in, test.err} + test.err = &strconv.NumError{Func: "ParseInt", Num: test.in, Err: test.err} } } for i := range parseUint32Tests { test := &parseUint32Tests[i] if test.err != nil { - test.err = &strconv.NumError{"ParseUint", test.in, test.err} + test.err = &strconv.NumError{Func: "ParseUint", Num: test.in, Err: test.err} } } for i := range parseInt32Tests { test := &parseInt32Tests[i] if test.err != nil { - test.err = &strconv.NumError{"ParseInt", test.in, test.err} + test.err = &strconv.NumError{Func: "ParseInt", Num: test.in, Err: test.err} } } } @@ -350,9 +350,9 @@ func init() { func TestParseUint32(t *testing.T) { for i := range parseUint32Tests { test := &parseUint32Tests[i] - out, err := ParseUint(test.in, 10, 32) + out, err := parseUint(test.in, 10, 32) if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseUint(%q, 10, 32) = %v, %v want %v, %v", + t.Errorf("parseUint(%q, 10, 32) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) } } @@ -361,9 +361,9 @@ func TestParseUint32(t *testing.T) { func TestParseUint64(t *testing.T) { for i := range parseUint64Tests { test := &parseUint64Tests[i] - out, err := ParseUint(test.in, 10, 64) + out, err := parseUint(test.in, 10, 64) if test.out != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseUint(%q, 10, 64) = %v, %v want %v, %v", + t.Errorf("parseUint(%q, 10, 64) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) } } @@ -372,9 +372,9 @@ func TestParseUint64(t *testing.T) { func TestParseUint64Base(t *testing.T) { for i := range parseUint64BaseTests { test := &parseUint64BaseTests[i] - out, err := ParseUint(test.in, test.base, 64) + out, err := parseUint(test.in, test.base, 64) if test.out != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseUint(%q, %v, 64) = %v, %v want %v, %v", + t.Errorf("parseUint(%q, %v, 64) = %v, %v want %v, %v", test.in, test.base, out, err, test.out, test.err) } } @@ -383,9 +383,9 @@ func TestParseUint64Base(t *testing.T) { func TestParseInt32(t *testing.T) { for i := range parseInt32Tests { test := &parseInt32Tests[i] - out, err := ParseInt(test.in, 10, 32) + out, err := parseInt(test.in, 10, 32) if int64(test.out) != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseInt(%q, 10 ,32) = %v, %v want %v, %v", + t.Errorf("parseInt(%q, 10 ,32) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) } } @@ -394,9 +394,9 @@ func TestParseInt32(t *testing.T) { func TestParseInt64(t *testing.T) { for i := range parseInt64Tests { test := &parseInt64Tests[i] - out, err := ParseInt(test.in, 10, 64) + out, err := parseInt(test.in, 10, 64) if test.out != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseInt(%q, 10, 64) = %v, %v want %v, %v", + t.Errorf("parseInt(%q, 10, 64) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) } } @@ -405,9 +405,9 @@ func TestParseInt64(t *testing.T) { func TestParseInt64Base(t *testing.T) { for i := range parseInt64BaseTests { test := &parseInt64BaseTests[i] - out, err := ParseInt(test.in, test.base, 64) + out, err := parseInt(test.in, test.base, 64) if test.out != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseInt(%q, %v, 64) = %v, %v want %v, %v", + t.Errorf("parseInt(%q, %v, 64) = %v, %v want %v, %v", test.in, test.base, out, err, test.out, test.err) } } @@ -418,18 +418,18 @@ func TestParseUint(t *testing.T) { case 32: for i := range parseUint32Tests { test := &parseUint32Tests[i] - out, err := ParseUint(test.in, 10, 0) + out, err := parseUint(test.in, 10, 0) if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v", + t.Errorf("parseUint(%q, 10, 0) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) } } case 64: for i := range parseUint64Tests { test := &parseUint64Tests[i] - out, err := ParseUint(test.in, 10, 0) + out, err := parseUint(test.in, 10, 0) if test.out != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v", + t.Errorf("parseUint(%q, 10, 0) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) } } @@ -441,18 +441,18 @@ func TestParseInt(t *testing.T) { case 32: for i := range parseInt32Tests { test := &parseInt32Tests[i] - out, err := ParseInt(test.in, 10, 0) + out, err := parseInt(test.in, 10, 0) if int64(test.out) != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v", + t.Errorf("parseInt(%q, 10, 0) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) } } case 64: for i := range parseInt64Tests { test := &parseInt64Tests[i] - out, err := ParseInt(test.in, 10, 0) + out, err := parseInt(test.in, 10, 0) if test.out != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v", + t.Errorf("parseInt(%q, 10, 0) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) } } @@ -538,9 +538,9 @@ func TestParseIntBitSize(t *testing.T) { for i := range parseBitSizeTests { test := &parseBitSizeTests[i] testErr := test.errStub("ParseInt", test.arg) - _, err := ParseInt("0", 0, test.arg) + _, err := parseInt("0", 0, test.arg) if !equalError(testErr, err) { - t.Errorf("ParseInt(\"0\", 0, %v) = 0, %v want 0, %v", + t.Errorf("parseInt(\"0\", 0, %v) = 0, %v want 0, %v", test.arg, err, testErr) } } @@ -550,9 +550,9 @@ func TestParseUintBitSize(t *testing.T) { for i := range parseBitSizeTests { test := &parseBitSizeTests[i] testErr := test.errStub("ParseUint", test.arg) - _, err := ParseUint("0", 0, test.arg) + _, err := parseUint("0", 0, test.arg) if !equalError(testErr, err) { - t.Errorf("ParseUint(\"0\", 0, %v) = 0, %v want 0, %v", + t.Errorf("parseUint(\"0\", 0, %v) = 0, %v want 0, %v", test.arg, err, testErr) } } @@ -562,9 +562,9 @@ func TestParseIntBase(t *testing.T) { for i := range parseBaseTests { test := &parseBaseTests[i] testErr := test.errStub("ParseInt", test.arg) - _, err := ParseInt("0", test.arg, 0) + _, err := parseInt("0", test.arg, 0) if !equalError(testErr, err) { - t.Errorf("ParseInt(\"0\", %v, 0) = 0, %v want 0, %v", + t.Errorf("parseInt(\"0\", %v, 0) = 0, %v want 0, %v", test.arg, err, testErr) } } @@ -574,9 +574,9 @@ func TestParseUintBase(t *testing.T) { for i := range parseBaseTests { test := &parseBaseTests[i] testErr := test.errStub("ParseUint", test.arg) - _, err := ParseUint("0", test.arg, 0) + _, err := parseUint("0", test.arg, 0) if !equalError(testErr, err) { - t.Errorf("ParseUint(\"0\", %v, 0) = 0, %v want 0, %v", + t.Errorf("parseUint(\"0\", %v, 0) = 0, %v want 0, %v", test.arg, err, testErr) } } @@ -595,12 +595,12 @@ func TestNumError(t *testing.T) { } } -func BenchmarkParseInt(b *testing.B) { +func BenchmarkparseInt(b *testing.B) { b.Run("Pos", func(b *testing.B) { - benchmarkParseInt(b, 1) + benchmarkparseInt(b, 1) }) b.Run("Neg", func(b *testing.B) { - benchmarkParseInt(b, -1) + benchmarkparseInt(b, -1) }) } @@ -609,7 +609,7 @@ type benchCase struct { num int64 } -func benchmarkParseInt(b *testing.B, neg int) { +func benchmarkparseInt(b *testing.B, neg int) { cases := []benchCase{ {"7bit", 1<<7 - 1}, {"26bit", 1<<26 - 1}, @@ -621,7 +621,7 @@ func benchmarkParseInt(b *testing.B, neg int) { b.Run(cs.name, func(b *testing.B) { s := fmt.Sprintf("%d", cs.num*int64(neg)) for i := 0; i < b.N; i++ { - out, _ := ParseInt(s, 10, 64) + out, _ := parseInt(s, 10, 64) BenchSink += int(out) } }) @@ -661,7 +661,7 @@ func benchmarkAtoi(b *testing.B, neg int) { } func TestAtoi62(t *testing.T) { - i, err := ParseUint("aZl8N0y58M7", 62, 64) + i, err := parseUint("aZl8N0y58M7", 62, 64) assert.NoError(t, err) assert.Equal(t, uint64(9223372036854775807), i) } diff --git a/digit/converts.go b/digit/converts.go index 22ef70b..7451916 100644 --- a/digit/converts.go +++ b/digit/converts.go @@ -5,6 +5,8 @@ import ( "math" "reflect" "strconv" + + "github.com/andeya/gust" ) // TryFromString converts ~string to digit. @@ -13,56 +15,64 @@ import ( // and base 10 otherwise. Also, for base == 0 only, underscore // characters are permitted per the Go integer literal syntax. // If base is below 0, is 1, or is above 62, an error is returned. -func TryFromString[T ~string, D Digit](v T, base int, bitSize int) (D, error) { +func TryFromString[T ~string, D gust.Digit](v T, base int, bitSize int) gust.Result[D] { + return gust.Ret[D](tryFromString[T, D](v, base, bitSize)) +} + +func tryFromString[T ~string, D gust.Digit](v T, base int, bitSize int) (D, error) { var d *D var x interface{} = d switch x.(type) { case *int, *int8, *int16, *int32, *int64: - r, err := ParseInt(string(v), base, bitSize) + r, err := parseInt(string(v), base, bitSize) if err != nil { return 0, err } - return As[int64, D](r) + return as[int64, D](r) case *uint, *uint8, *uint16, *uint32, *uint64: - r, err := ParseUint(string(v), base, bitSize) + r, err := parseUint(string(v), base, bitSize) if err != nil { return 0, err } - return As[uint64, D](r) + return as[uint64, D](r) case *float32, *float64: r, err := strconv.ParseFloat(string(v), bitSize) if err != nil { return 0, err } - return As[float64, D](r) + return as[float64, D](r) } switch reflect.TypeOf(x).Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - r, err := ParseInt(string(v), base, bitSize) + r, err := parseInt(string(v), base, bitSize) if err != nil { return 0, err } - return As[int64, D](r) + return as[int64, D](r) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - r, err := ParseUint(string(v), base, bitSize) + r, err := parseUint(string(v), base, bitSize) if err != nil { return 0, err } - return As[uint64, D](r) + return as[uint64, D](r) case reflect.Float32, reflect.Float64: r, err := strconv.ParseFloat(string(v), bitSize) if err != nil { return 0, err } - return As[float64, D](r) + return as[float64, D](r) } return 0, nil } -func TryFromStrings[T ~string, D Digit](a []T, base int, bitSize int) (b []D, err error) { +func TryFromStrings[T ~string, D gust.Digit](a []T, base int, bitSize int) gust.Result[[]D] { + return gust.Ret(tryFromStrings[T, D](a, base, bitSize)) +} + +func tryFromStrings[T ~string, D gust.Digit](a []T, base int, bitSize int) (b []D, err error) { b = make([]D, len(a)) for i, t := range a { - b[i], err = TryFromString[T, D](t, base, bitSize) + b[i], err = tryFromString[T, D](t, base, bitSize) if err != nil { return nil, err } @@ -71,13 +81,13 @@ func TryFromStrings[T ~string, D Digit](a []T, base int, bitSize int) (b []D, er } // ToBool converts D to bool. -func ToBool[T Digit](v T) bool { +func ToBool[T gust.Digit](v T) bool { zero := new(T) return v != *zero } // ToBools converts []D to []bool. -func ToBools[T Digit](a []T) []bool { +func ToBools[T gust.Digit](a []T) []bool { b := make([]bool, len(a)) for i, t := range a { b[i] = ToBool(t) @@ -86,14 +96,14 @@ func ToBools[T Digit](a []T) []bool { } // FromBool converts bool to digit. -func FromBool[T ~bool, D Digit](v T) D { +func FromBool[T ~bool, D gust.Digit](v T) D { if v == true { return D(1) } return D(0) } -func FromBools[T ~bool, D Digit](a []T) (b []D) { +func FromBools[T ~bool, D gust.Digit](a []T) (b []D) { b = make([]D, len(a)) for i, t := range a { b[i] = FromBool[T, D](t) @@ -101,7 +111,11 @@ func FromBools[T ~bool, D Digit](a []T) (b []D) { return b } -func As[T Digit, D Digit](v T) (D, error) { +func As[T gust.Digit, D gust.Digit](v T) gust.Result[D] { + return gust.Ret(as[T, D](v)) +} + +func as[T gust.Digit, D gust.Digit](v T) (D, error) { var d *D var x interface{} = d switch x.(type) { @@ -184,10 +198,10 @@ func As[T Digit, D Digit](v T) (D, error) { } // SliceAs creates a copy of the digit slice. -func SliceAs[T Digit, D Digit](a []T) (b []D, err error) { +func SliceAs[T gust.Digit, D gust.Digit](a []T) (b []D, err error) { b = make([]D, len(a)) for i, t := range a { - b[i], err = As[T, D](t) + b[i], err = as[T, D](t) if err != nil { return nil, err } @@ -196,12 +210,12 @@ func SliceAs[T Digit, D Digit](a []T) (b []D, err error) { } // digitToFloat64 converts digit to float64. -func digitToFloat64[T Digit](v T) float64 { +func digitToFloat64[T gust.Digit](v T) float64 { return float64(v) } // digitToFloat32 converts digit to float32. -func digitToFloat32[T Digit](v T) (float32, error) { +func digitToFloat32[T gust.Digit](v T) (float32, error) { f := float64(v) if f > math.MaxFloat32 || f < -math.MaxFloat32 { return 0, errOverflowValue @@ -210,7 +224,7 @@ func digitToFloat32[T Digit](v T) (float32, error) { } // digitToInt converts digit to int. -func digitToInt[T Digit](v T) (int, error) { +func digitToInt[T gust.Digit](v T) (int, error) { f := float64(v) if f > math.MaxInt || f < math.MinInt { return 0, errOverflowValue @@ -219,7 +233,7 @@ func digitToInt[T Digit](v T) (int, error) { } // digitToInt8 converts digit to int8. -func digitToInt8[T Digit](v T) (int8, error) { +func digitToInt8[T gust.Digit](v T) (int8, error) { if v > 0 { if v > math.MaxInt8 { return 0, errOverflowValue @@ -233,7 +247,7 @@ func digitToInt8[T Digit](v T) (int8, error) { } // digitToInt16 converts digit to int16. -func digitToInt16[T Digit](v T) (int16, error) { +func digitToInt16[T gust.Digit](v T) (int16, error) { f := float64(v) if f > math.MaxInt16 || f < math.MinInt16 { return 0, errOverflowValue @@ -242,7 +256,7 @@ func digitToInt16[T Digit](v T) (int16, error) { } // digitToInt32 converts digit to int32. -func digitToInt32[T Digit](v T) (int32, error) { +func digitToInt32[T gust.Digit](v T) (int32, error) { f := float64(v) if f > math.MaxInt32 || f < math.MinInt32 { return 0, errOverflowValue @@ -251,7 +265,7 @@ func digitToInt32[T Digit](v T) (int32, error) { } // digitToInt64 converts digit to int64. -func digitToInt64[T Digit](v T) (int64, error) { +func digitToInt64[T gust.Digit](v T) (int64, error) { f := float64(v) if f > math.MaxInt64 || f < math.MinInt64 { return 0, errOverflowValue @@ -260,7 +274,7 @@ func digitToInt64[T Digit](v T) (int64, error) { } // digitToUint converts digit to uint. -func digitToUint[T Digit](v T) (uint, error) { +func digitToUint[T gust.Digit](v T) (uint, error) { if v < 0 { return 0, errNegativeValue } @@ -271,7 +285,7 @@ func digitToUint[T Digit](v T) (uint, error) { } // digitToUint8 converts digit to uint8. -func digitToUint8[T Digit](v T) (uint8, error) { +func digitToUint8[T gust.Digit](v T) (uint8, error) { if v < 0 { return 0, errNegativeValue } @@ -282,7 +296,7 @@ func digitToUint8[T Digit](v T) (uint8, error) { } // digitToUint16 converts digit to uint16. -func digitToUint16[T Digit](v T) (uint16, error) { +func digitToUint16[T gust.Digit](v T) (uint16, error) { if v < 0 { return 0, errNegativeValue } @@ -293,7 +307,7 @@ func digitToUint16[T Digit](v T) (uint16, error) { } // digitToUint32 converts digit to uint32. -func digitToUint32[T Digit](v T) (uint32, error) { +func digitToUint32[T gust.Digit](v T) (uint32, error) { if v < 0 { return 0, errNegativeValue } @@ -304,7 +318,7 @@ func digitToUint32[T Digit](v T) (uint32, error) { } // digitToUint64 converts digit to uint64. -func digitToUint64[T Digit](v T) (uint64, error) { +func digitToUint64[T gust.Digit](v T) (uint64, error) { if v < 0 { return 0, errNegativeValue } diff --git a/digit/dict_num.go b/digit/dict_num.go index 0368a72..7fd9e42 100644 --- a/digit/dict_num.go +++ b/digit/dict_num.go @@ -5,6 +5,8 @@ import ( "errors" "fmt" "math" + + "github.com/andeya/gust" ) // FormatByDict convert num into corresponding string according to dict. @@ -28,9 +30,9 @@ func FormatByDict(dict []byte, num uint64) string { } // ParseByDict convert numStr into corresponding digit according to dict. -func ParseByDict[D Digit](dict []byte, numStr string) (D, error) { +func ParseByDict[D gust.Digit](dict []byte, numStr string) gust.Result[D] { if len(dict) == 0 { - return 0, errors.New("dict is empty") + return gust.Err[D](errors.New("dict is empty")) } base := float64(len(dict)) len := len(numStr) @@ -39,9 +41,9 @@ func ParseByDict[D Digit](dict []byte, numStr string) (D, error) { char := numStr[i : i+1] pos := bytes.IndexAny(dict, char) if pos == -1 { - return 0, fmt.Errorf("found a char not included in the dict: %q", char) + return gust.Err[D](fmt.Errorf("found a char not included in the dict: %q", char)) } number = math.Pow(base, float64(len-i-1))*float64(pos) + number } - return D(number), nil + return gust.Ok(D(number)) } diff --git a/digit/dict_num_test.go b/digit/dict_num_test.go index 22eda2e..311632b 100644 --- a/digit/dict_num_test.go +++ b/digit/dict_num_test.go @@ -11,18 +11,18 @@ func TestFormatByDict(t *testing.T) { for i := uint64(0); i < 100; i++ { numStr := FormatByDict(dict, i) t.Logf("i=%d, s=%s", i, numStr) - i2, err := ParseByDict[uint64](dict, numStr) - assert.NoError(t, err) - assert.Equal(t, i, i2) + r := ParseByDict[uint64](dict, numStr) + assert.False(t, r.IsErr()) + assert.Equal(t, i, r.Unwrap()) } } func TestParseByDict(t *testing.T) { dict := []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ") numStr := "DDEZQ" - num, err := ParseByDict[uint64](dict, numStr) - assert.NoError(t, err) - t.Logf("DDEZQ=%d", num) // DDEZQ=1427026 - numStr2 := FormatByDict(dict, num) + r := ParseByDict[uint64](dict, numStr) + assert.False(t, r.IsErr()) + t.Logf("DDEZQ=%d", r.Unwrap()) // DDEZQ=1427026 + numStr2 := FormatByDict(dict, r.Unwrap()) assert.Equal(t, numStr2, numStr) } diff --git a/digit/utils.go b/digit/utils.go index 78b0ceb..caba8fc 100644 --- a/digit/utils.go +++ b/digit/utils.go @@ -12,7 +12,7 @@ const ( Host32bit = ^uint(0)>>32 == 0 ) -func Abs[T Digit](d T) T { +func Abs[T gust.Digit](d T) T { var zero T if d < zero { return -d @@ -20,7 +20,7 @@ func Abs[T Digit](d T) T { return d } -func Max[T Integer]() T { +func Max[T gust.Integer]() T { var t T switch any(t).(type) { case int: @@ -57,28 +57,28 @@ func Max[T Integer]() T { } } -func SaturatingAdd[T Integer](a, b T) T { +func SaturatingAdd[T gust.Integer](a, b T) T { if a < Max[T]()-b { return a + b } return Max[T]() } -func SaturatingSub[T Digit](a, b T) T { +func SaturatingSub[T gust.Digit](a, b T) T { if a > b { return a - b } return 0 } -func CheckedAdd[T Integer](a, b T) gust.Option[T] { +func CheckedAdd[T gust.Integer](a, b T) gust.Option[T] { if a <= Max[T]()-b { return gust.Some(a + b) } return gust.None[T]() } -func CheckedMul[T Integer](a, b T) gust.Option[T] { +func CheckedMul[T gust.Integer](a, b T) gust.Option[T] { if a <= Max[T]()/b { return gust.Some(a * b) } diff --git a/examples/iterator/reduce_test.go b/examples/iterator/reduce_test.go index ad8bca4..d0da056 100644 --- a/examples/iterator/reduce_test.go +++ b/examples/iterator/reduce_test.go @@ -4,12 +4,11 @@ import ( "testing" "github.com/andeya/gust" - "github.com/andeya/gust/digit" "github.com/andeya/gust/iter" "github.com/stretchr/testify/assert" ) -func findMax[T digit.Integer](i iter.Iterator[T]) gust.Option[T] { +func findMax[T gust.Integer](i iter.Iterator[T]) gust.Option[T] { return i.Reduce(func(acc T, v T) T { if acc >= v { return acc diff --git a/iter/export.go b/iter/export.go index 2f198ff..4ed5bcc 100644 --- a/iter/export.go +++ b/iter/export.go @@ -5,7 +5,6 @@ import ( "unsafe" "github.com/andeya/gust" - "github.com/andeya/gust/digit" ) // FromIterable creates an iterator from an Iterable. @@ -57,12 +56,12 @@ func EnumElements[T any](elems ...T) DeIterator[KV[T]] { } // FromRange creates a double ended iterator from a range. -func FromRange[T digit.Integer](start T, end T, rightClosed ...bool) DeIterator[T] { +func FromRange[T gust.Integer](start T, end T, rightClosed ...bool) DeIterator[T] { return NewIterableRange[T](start, end, rightClosed...).ToDeIterator() } // EnumRange creates a double ended iterator with index from a range. -func EnumRange[T digit.Integer](start T, end T, rightClosed ...bool) DeIterator[KV[T]] { +func EnumRange[T gust.Integer](start T, end T, rightClosed ...bool) DeIterator[KV[T]] { return ToDeEnumerate[T](FromRange[T](start, end, rightClosed...)) } diff --git a/iter/iterable_range.go b/iter/iterable_range.go index 500d3c9..96525ee 100644 --- a/iter/iterable_range.go +++ b/iter/iterable_range.go @@ -2,7 +2,6 @@ package iter import ( "github.com/andeya/gust" - "github.com/andeya/gust/digit" ) var ( @@ -12,13 +11,13 @@ var ( _ gust.DeIterable[uint] = (*IterableRange[uint])(nil) ) -type IterableRange[T digit.Integer] struct { +type IterableRange[T gust.Integer] struct { nextValue T backNextValue T ended bool } -func NewIterableRange[T digit.Integer](start T, end T, rightClosed ...bool) *IterableRange[T] { +func NewIterableRange[T gust.Integer](start T, end T, rightClosed ...bool) *IterableRange[T] { max := end if len(rightClosed) == 0 || !rightClosed[0] { if end <= start { diff --git a/ord/ordering.go b/ordering.go similarity index 87% rename from ord/ordering.go rename to ordering.go index 60a1ee3..183ad08 100644 --- a/ord/ordering.go +++ b/ordering.go @@ -1,9 +1,7 @@ -package ord - -import "github.com/andeya/gust/digit" +package gust type Ord interface { - digit.Digit | ~string | ~uintptr + Digit | ~string | ~uintptr } type Ordering struct {