Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / xerrors@v0.0.0-20200804184101-5ec99f83aff1 / adaptor.go
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package xerrors
6
7 import (
8         "bytes"
9         "fmt"
10         "io"
11         "reflect"
12         "strconv"
13 )
14
15 // FormatError calls the FormatError method of f with an errors.Printer
16 // configured according to s and verb, and writes the result to s.
17 func FormatError(f Formatter, s fmt.State, verb rune) {
18         // Assuming this function is only called from the Format method, and given
19         // that FormatError takes precedence over Format, it cannot be called from
20         // any package that supports errors.Formatter. It is therefore safe to
21         // disregard that State may be a specific printer implementation and use one
22         // of our choice instead.
23
24         // limitations: does not support printing error as Go struct.
25
26         var (
27                 sep    = " " // separator before next error
28                 p      = &state{State: s}
29                 direct = true
30         )
31
32         var err error = f
33
34         switch verb {
35         // Note that this switch must match the preference order
36         // for ordinary string printing (%#v before %+v, and so on).
37
38         case 'v':
39                 if s.Flag('#') {
40                         if stringer, ok := err.(fmt.GoStringer); ok {
41                                 io.WriteString(&p.buf, stringer.GoString())
42                                 goto exit
43                         }
44                         // proceed as if it were %v
45                 } else if s.Flag('+') {
46                         p.printDetail = true
47                         sep = "\n  - "
48                 }
49         case 's':
50         case 'q', 'x', 'X':
51                 // Use an intermediate buffer in the rare cases that precision,
52                 // truncation, or one of the alternative verbs (q, x, and X) are
53                 // specified.
54                 direct = false
55
56         default:
57                 p.buf.WriteString("%!")
58                 p.buf.WriteRune(verb)
59                 p.buf.WriteByte('(')
60                 switch {
61                 case err != nil:
62                         p.buf.WriteString(reflect.TypeOf(f).String())
63                 default:
64                         p.buf.WriteString("<nil>")
65                 }
66                 p.buf.WriteByte(')')
67                 io.Copy(s, &p.buf)
68                 return
69         }
70
71 loop:
72         for {
73                 switch v := err.(type) {
74                 case Formatter:
75                         err = v.FormatError((*printer)(p))
76                 case fmt.Formatter:
77                         v.Format(p, 'v')
78                         break loop
79                 default:
80                         io.WriteString(&p.buf, v.Error())
81                         break loop
82                 }
83                 if err == nil {
84                         break
85                 }
86                 if p.needColon || !p.printDetail {
87                         p.buf.WriteByte(':')
88                         p.needColon = false
89                 }
90                 p.buf.WriteString(sep)
91                 p.inDetail = false
92                 p.needNewline = false
93         }
94
95 exit:
96         width, okW := s.Width()
97         prec, okP := s.Precision()
98
99         if !direct || (okW && width > 0) || okP {
100                 // Construct format string from State s.
101                 format := []byte{'%'}
102                 if s.Flag('-') {
103                         format = append(format, '-')
104                 }
105                 if s.Flag('+') {
106                         format = append(format, '+')
107                 }
108                 if s.Flag(' ') {
109                         format = append(format, ' ')
110                 }
111                 if okW {
112                         format = strconv.AppendInt(format, int64(width), 10)
113                 }
114                 if okP {
115                         format = append(format, '.')
116                         format = strconv.AppendInt(format, int64(prec), 10)
117                 }
118                 format = append(format, string(verb)...)
119                 fmt.Fprintf(s, string(format), p.buf.String())
120         } else {
121                 io.Copy(s, &p.buf)
122         }
123 }
124
125 var detailSep = []byte("\n    ")
126
127 // state tracks error printing state. It implements fmt.State.
128 type state struct {
129         fmt.State
130         buf bytes.Buffer
131
132         printDetail bool
133         inDetail    bool
134         needColon   bool
135         needNewline bool
136 }
137
138 func (s *state) Write(b []byte) (n int, err error) {
139         if s.printDetail {
140                 if len(b) == 0 {
141                         return 0, nil
142                 }
143                 if s.inDetail && s.needColon {
144                         s.needNewline = true
145                         if b[0] == '\n' {
146                                 b = b[1:]
147                         }
148                 }
149                 k := 0
150                 for i, c := range b {
151                         if s.needNewline {
152                                 if s.inDetail && s.needColon {
153                                         s.buf.WriteByte(':')
154                                         s.needColon = false
155                                 }
156                                 s.buf.Write(detailSep)
157                                 s.needNewline = false
158                         }
159                         if c == '\n' {
160                                 s.buf.Write(b[k:i])
161                                 k = i + 1
162                                 s.needNewline = true
163                         }
164                 }
165                 s.buf.Write(b[k:])
166                 if !s.inDetail {
167                         s.needColon = true
168                 }
169         } else if !s.inDetail {
170                 s.buf.Write(b)
171         }
172         return len(b), nil
173 }
174
175 // printer wraps a state to implement an xerrors.Printer.
176 type printer state
177
178 func (s *printer) Print(args ...interface{}) {
179         if !s.inDetail || s.printDetail {
180                 fmt.Fprint((*state)(s), args...)
181         }
182 }
183
184 func (s *printer) Printf(format string, args ...interface{}) {
185         if !s.inDetail || s.printDetail {
186                 fmt.Fprintf((*state)(s), format, args...)
187         }
188 }
189
190 func (s *printer) Detail() bool {
191         s.inDetail = true
192         return s.printDetail
193 }