From 466faaab9f7dbcdb51b286b8416edd36fb6fea65 Mon Sep 17 00:00:00 2001 From: Vincent Serpoul Date: Fri, 23 Apr 2021 22:41:21 +0800 Subject: [PATCH] golangci-lint: marshaler, strict (#523) --- .golangci.toml | 2 +- marshaler.go | 47 ++++++++++++++++++++++++++++------------------- marshaler_test.go | 8 ++++++++ strict.go | 9 +++++++++ 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/.golangci.toml b/.golangci.toml index 3d338e1..a38c60b 100644 --- a/.golangci.toml +++ b/.golangci.toml @@ -27,7 +27,7 @@ enable = [ "forcetypeassert", "funlen", "gci", - "gochecknoglobals", + # "gochecknoglobals", "gochecknoinits", "gocognit", "goconst", diff --git a/marshaler.go b/marshaler.go index 06f11a1..67513b0 100644 --- a/marshaler.go +++ b/marshaler.go @@ -49,19 +49,19 @@ func NewEncoder(w io.Writer) *Encoder { // SetTablesInline forces the encoder to emit all tables inline. // -// This behavior can be controled on an individual struct field basis with the +// This behavior can be controlled on an individual struct field basis with the // `inline="true"` tag. -func (e *Encoder) SetTablesInline(inline bool) { - e.tablesInline = inline +func (enc *Encoder) SetTablesInline(inline bool) { + enc.tablesInline = inline } // SetArraysMultiline forces the encoder to emit all arrays with one element per // line. // -// This behavior can be controled on an individual struct field basis with the +// This behavior can be controlled on an individual struct field basis with the // `multiline="true"` tag. -func (e *Encoder) SetArraysMultiline(multiline bool) { - e.arraysMultiline = multiline +func (enc *Encoder) SetArraysMultiline(multiline bool) { + enc.arraysMultiline = multiline } // Encode writes a TOML representation of v to the stream. @@ -165,18 +165,18 @@ func (ctx *encoderCtx) isRoot() bool { return len(ctx.parentKey) == 0 && !ctx.hasKey } -var errUnsupportedValue = errors.New("unsupported encode value kind") -var errTextMarshalerCannotBeAtRoot = errors.New("type implementing TextMarshaler cannot be at root") +var ( + errUnsupportedValue = errors.New("unsupported encode value kind") + errTextMarshalerCannotBeAtRoot = errors.New("type implementing TextMarshaler cannot be at root") +) -//nolint:cyclop +//nolint:cyclop,funlen func (enc *Encoder) encode(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, error) { - //nolint:gocritic,godox - - if v.Type() == timeType { - i := v.Interface().(time.Time) - b = i.AppendFormat(b, time.RFC3339) - return b, nil + i, ok := v.Interface().(time.Time) + if ok { + return i.AppendFormat(b, time.RFC3339), nil } + if v.Type().Implements(textMarshalerType) { if ctx.isRoot() { return nil, errTextMarshalerCannotBeAtRoot @@ -184,9 +184,11 @@ func (enc *Encoder) encode(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, e text, err := v.Interface().(encoding.TextMarshaler).MarshalText() if err != nil { - return nil, err + return nil, fmt.Errorf("encode: %w", err) } + b = enc.encodeString(b, string(text), ctx.options) + return b, nil } @@ -543,6 +545,7 @@ func (enc *Encoder) encodeStruct(b []byte, ctx encoderCtx, v reflect.Value) ([]b func fieldBoolTag(field reflect.StructField, tag string) bool { x, ok := field.Tag.Lookup(tag) + return ok && x == "true" } @@ -578,6 +581,7 @@ func (enc *Encoder) encodeTable(b []byte, ctx encoderCtx, t table) ([]byte, erro ctx.setKey(table.Key) ctx.options = table.Options + b, err = enc.encode(b, ctx, table.Value) if err != nil { return nil, err @@ -632,9 +636,10 @@ func (enc *Encoder) encodeTableInline(b []byte, ctx encoderCtx, t table) ([]byte return b, nil } -var errNilInterface = errors.New("nil interface not supported") - -var textMarshalerType = reflect.TypeOf(new(encoding.TextMarshaler)).Elem() +var ( + errNilInterface = errors.New("nil interface not supported") + textMarshalerType = reflect.TypeOf(new(encoding.TextMarshaler)).Elem() +) func willConvertToTable(ctx encoderCtx, v reflect.Value) (bool, error) { if v.Type() == timeType || v.Type().Implements(textMarshalerType) { @@ -765,7 +770,9 @@ func (enc *Encoder) encodeSliceAsArray(b []byte, ctx encoderCtx, v reflect.Value if multiline { separator = ",\n" + b = append(b, '\n') + subCtx.indent++ } @@ -793,6 +800,7 @@ func (enc *Encoder) encodeSliceAsArray(b []byte, ctx encoderCtx, v reflect.Value b = append(b, '\n') b = enc.indent(ctx.indent, b) } + b = append(b, ']') return b, nil @@ -802,5 +810,6 @@ func (enc *Encoder) indent(level int, b []byte) []byte { for i := 0; i < level; i++ { b = append(b, enc.indentSymbol...) } + return b } diff --git a/marshaler_test.go b/marshaler_test.go index e0a349f..8d64182 100644 --- a/marshaler_test.go +++ b/marshaler_test.go @@ -308,6 +308,7 @@ A = [ b, err := toml.Marshal(e.v) if e.err { require.Error(t, err) + return } @@ -320,6 +321,8 @@ A = [ require.NoError(t, err) testWithAllFlags(t, func(t *testing.T, flags int) { + t.Helper() + var buf bytes.Buffer enc := toml.NewEncoder(&buf) setFlags(enc, flags) @@ -364,6 +367,7 @@ func testWithFlags(t *testing.T, flags int, setters flagsSetters, testfn func(t if len(setters) == 0 { testfn(t, flags) + return } @@ -372,9 +376,11 @@ func testWithFlags(t *testing.T, flags int, setters flagsSetters, testfn func(t for _, enabled := range []bool{false, true} { name := fmt.Sprintf("%s=%t", s.name, enabled) newFlags := flags << 1 + if enabled { newFlags++ } + t.Run(name, func(t *testing.T) { testWithFlags(t, newFlags, setters[1:], testfn) }) @@ -409,6 +415,8 @@ c = 'd' } func TestIssue424(t *testing.T) { + t.Parallel() + type Message1 struct { Text string } diff --git a/strict.go b/strict.go index 236ad64..2b2e7d6 100644 --- a/strict.go +++ b/strict.go @@ -18,6 +18,7 @@ func (s *strict) EnterTable(node ast.Node) { if !s.Enabled { return } + s.key.UpdateTable(node) } @@ -25,6 +26,7 @@ func (s *strict) EnterArrayTable(node ast.Node) { if !s.Enabled { return } + s.key.UpdateArrayTable(node) } @@ -32,6 +34,7 @@ func (s *strict) EnterKeyValue(node ast.Node) { if !s.Enabled { return } + s.key.Push(node) } @@ -39,6 +42,7 @@ func (s *strict) ExitKeyValue(node ast.Node) { if !s.Enabled { return } + s.key.Pop(node) } @@ -46,6 +50,7 @@ func (s *strict) MissingTable(node ast.Node) { if !s.Enabled { return } + s.missing = append(s.missing, decodeError{ highlight: keyLocation(node), message: "missing table", @@ -57,6 +62,7 @@ func (s *strict) MissingField(node ast.Node) { if !s.Enabled { return } + s.missing = append(s.missing, decodeError{ highlight: keyLocation(node), message: "missing field", @@ -72,8 +78,11 @@ func (s *strict) Error(doc []byte) error { err := &StrictMissingError{ Errors: make([]DecodeError, 0, len(s.missing)), } + for _, derr := range s.missing { + derr := derr err.Errors = append(err.Errors, *wrapDecodeError(doc, &derr)) } + return err }