diff --git a/.golangci.yml b/.golangci.yml index c725388..453957e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -16,3 +16,4 @@ linters: - staticcheck - typecheck - unused + - gocyclo diff --git a/CHANGELOG.md b/CHANGELOG.md index ca833c8..7f40666 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [0.1.7] - 2023-08-20 + +### Changed + +- Enabled `gocyclo` linter. + ## [0.1.6] - 2023-08-19 ### Added diff --git a/decimal.go b/decimal.go index 9622af7..b4d4288 100644 --- a/decimal.go +++ b/decimal.go @@ -276,6 +276,8 @@ func ParseExact(s string, scale int) (Decimal, error) { } // parseFint does not support exponential notation to make it as fast as possible. +// +//gocylo:ignore func parseFint(s string, minScale int) (Decimal, error) { pos := 0 width := len(s) @@ -329,6 +331,8 @@ func parseFint(s string, minScale int) (Decimal, error) { } // parseSint supports exponential notation. +// +//gocylo:ignore func parseSint(s string, minScale int) (Decimal, error) { pos := 0 width := len(s) @@ -538,7 +542,7 @@ func (d Decimal) MarshalText() ([]byte, error) { } // Scan implements the [sql.Scanner] interface. -// See also method [Decimal.Parse]. +// See also method [Parse]. // // [sql.Scanner]: https://pkg.go.dev/database/sql#Scanner func (d *Decimal) Scan(v any) error { @@ -579,14 +583,16 @@ func (d Decimal) Value() (driver.Value, error) { // // [verbs]: https://pkg.go.dev/fmt#hdr-Printing // [fmt.Formatter]: https://pkg.go.dev/fmt#Formatter +// +//gocyclo:ignore func (d Decimal) Format(state fmt.State, verb rune) { var err error - // Percentage + // Percentage multiplier if verb == 'k' || verb == 'K' { d, err = d.Mul(Hundred) if err != nil { - panic(fmt.Errorf("formatting percent: %w", err)) // this panic is handled by the fmt package + panic(fmt.Errorf("formatting percent: %w", err)) // this panic is handled inside the fmt package } } @@ -640,13 +646,13 @@ func (d Decimal) Format(state fmt.State, verb rune) { psign = 1 } - // Quotes + // Openning and closing quotes lquote, tquote := 0, 0 if verb == 'q' || verb == 'Q' { lquote, tquote = 1, 1 } - // Padding + // Calculating padding width := lquote + rsign + intdigs + dpoint + fracdigs + tzeroes + psign + tquote lspaces, tspaces, lzeroes := 0, 0, 0 if w, ok := state.Width(); ok && w > width { @@ -661,44 +667,61 @@ func (d Decimal) Format(state fmt.State, verb rune) { width = w } - // Writing buffer buf := make([]byte, width) pos := width - 1 + + // Trailing spaces for i := 0; i < tspaces; i++ { buf[pos] = ' ' pos-- } + + // Closing quote if tquote > 0 { buf[pos] = '"' pos-- } + + // Percentage sign if psign > 0 { buf[pos] = '%' pos-- } + + // Trailling zeroes for i := 0; i < tzeroes; i++ { buf[pos] = '0' pos-- } + + // Fractional digits dcoef := d.Coef() for i := 0; i < fracdigs; i++ { buf[pos] = byte(dcoef%10) + '0' pos-- dcoef /= 10 } + + // Decimal point if dpoint > 0 { buf[pos] = '.' pos-- } + + // Integer digits for i := 0; i < intdigs; i++ { buf[pos] = byte(dcoef%10) + '0' pos-- dcoef /= 10 } + + // Leading zeroes for i := 0; i < lzeroes; i++ { buf[pos] = '0' pos-- } + + // Arithmetic sign if rsign > 0 { if d.IsNeg() { buf[pos] = '-' @@ -709,10 +732,14 @@ func (d Decimal) Format(state fmt.State, verb rune) { } pos-- } + + // Opening quote if lquote > 0 { buf[pos] = '"' pos-- } + + // Leading spaces for i := 0; i < lspaces; i++ { buf[pos] = ' ' pos-- diff --git a/decimal_test.go b/decimal_test.go index 1670882..04de58b 100644 --- a/decimal_test.go +++ b/decimal_test.go @@ -1383,8 +1383,8 @@ func TestDecimal_Floor(t *testing.T) { func TestDecimal_MinScale(t *testing.T) { t.Run("success", func(t *testing.T) { tests := []struct { - decimal string - want int + d string + want int }{ {"0", 0}, {"0.0", 0}, @@ -1406,7 +1406,7 @@ func TestDecimal_MinScale(t *testing.T) { {"0.9999999999999999999", 19}, } for _, tt := range tests { - d := MustParse(tt.decimal) + d := MustParse(tt.d) got := d.MinScale() if got != tt.want { t.Errorf("%q.MinScale() = %v, want %v", d, got, tt.want) @@ -1752,9 +1752,9 @@ func TestDecimal_FMA(t *testing.T) { func TestDecimal_Pow(t *testing.T) { t.Run("success", func(t *testing.T) { tests := []struct { - decimal string - power int - want string + d string + power int + want string }{ // Zeroes {"0", 0, "1"}, @@ -1873,7 +1873,7 @@ func TestDecimal_Pow(t *testing.T) { {"1.00001", 600000, "403.4166908911752717"}, // should be 403.4166908911542153, error in the last six digits } for _, tt := range tests { - d := MustParse(tt.decimal) + d := MustParse(tt.d) got, err := d.Pow(tt.power) if err != nil { t.Errorf("%q.Pow(%d) failed: %v", d, tt.power, err) @@ -1888,7 +1888,7 @@ func TestDecimal_Pow(t *testing.T) { t.Run("error", func(t *testing.T) { tests := map[string]struct { - decimal string + d string power, scale int }{ "overflow 1": {"2", 64, 0}, @@ -1896,7 +1896,7 @@ func TestDecimal_Pow(t *testing.T) { "scale 1": {"1", 1, MaxScale}, } for _, tt := range tests { - d := MustParse(tt.decimal) + d := MustParse(tt.d) _, err := d.PowExact(tt.power, tt.scale) if err == nil { t.Errorf("%q.PowExact(%d, %d) did not fail", d, tt.power, tt.scale) @@ -1954,7 +1954,7 @@ func TestDecimal_CopySign(t *testing.T) { func TestDecimal_Neg(t *testing.T) { tests := []struct { - decimal, want string + d, want string }{ {"1", "-1"}, {"-1", "1"}, @@ -1965,7 +1965,7 @@ func TestDecimal_Neg(t *testing.T) { {"0.00", "0.00"}, } for _, tt := range tests { - d := MustParse(tt.decimal) + d := MustParse(tt.d) got := d.Neg() want := MustParse(tt.want) if got != want { @@ -2572,11 +2572,6 @@ func FuzzDecimalMul(f *testing.F) { t.Errorf("mulSint(%q, %q, %v) failed: %v", d, e, scale, err) return } - if s.Scale() < scale { - t.Errorf("mulSint(%q, %q, %v).Scale() = %v, want >= %v", d, e, scale, s.Scale(), scale) - return - } - if s.CmpTotal(f) != 0 { t.Errorf("mulSint(%q, %q, %v) = %q, whereas mulFint(%q, %q, %v) = %q", d, e, scale, s, d, e, scale, f) } @@ -2632,11 +2627,6 @@ func FuzzDecimalFMA(f *testing.F) { t.Errorf("fmaSint(%q, %q, %q, %v) failed: %v", d, e, g, scale, err) return } - if s.Scale() < scale { - t.Errorf("fmaSint(%q, %q, %q, %v).Scale() = %v, want >= %v", d, e, g, scale, s.Scale(), scale) - return - } - if s.CmpTotal(f) != 0 { t.Errorf("fmaSint(%q, %q, %q, %v) = %q, whereas fmaFint(%q, %q, %q, %v) = %q", d, e, g, scale, s, d, e, g, scale, f) } @@ -2685,11 +2675,6 @@ func FuzzDecimalAdd(f *testing.F) { t.Errorf("addSint(%q, %q, %v) failed: %v", d, e, scale, err) return } - if s.Scale() < scale { - t.Errorf("addSint(%q, %q, %v).Scale() = %v, want >= %v", d, e, scale, s.Scale(), scale) - return - } - if s.CmpTotal(f) != 0 { t.Errorf("addSint(%q, %q, %v) = %q, whereas addFint(%q, %q, %v) = %q", d, e, scale, s, d, e, scale, f) } @@ -2745,11 +2730,6 @@ func FuzzDecimalQuo(f *testing.F) { t.Errorf("quoSint(%q, %q, %v) failed: %v", d, e, scale, err) return } - if s.Scale() < scale { - t.Errorf("quoSint(%q, %q, %v).Scale() = %v, want >= %v", d, e, scale, s.Scale(), scale) - return - } - if s.Cmp(f) != 0 { t.Errorf("quoSint(%q, %q, %v) = %q, whereas quoFint(%q, %q, %v) = %q", d, e, scale, s, d, e, scale, f) }