-
Notifications
You must be signed in to change notification settings - Fork 1
/
errors.go
117 lines (105 loc) · 2.37 KB
/
errors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package splitter
import (
"fmt"
"strings"
)
// SplittingErrorType is the splitting error type - as used by splittingError
type SplittingErrorType int
const (
Unopened SplittingErrorType = iota
Unclosed
OptionFail
Wrapped
)
// SplittingError is the error type always returned from Splitter.Split
type SplittingError interface {
error
Type() SplittingErrorType
Position() int
Rune() rune
Enclosure() *Enclosure
Wrapped() error
Unwrap() error
}
type splittingError struct {
errorType SplittingErrorType
position int
rune rune
enc *Enclosure
wrapped error
message string
}
func newSplittingError(t SplittingErrorType, pos int, r rune, enc *Enclosure) SplittingError {
return &splittingError{
errorType: t,
position: pos,
rune: r,
enc: enc,
}
}
const (
unopenedFmt = "unopened '%s' at position %d"
unclosedFmt = "unclosed '%s' at position %d"
)
func (e *splittingError) Error() string {
if e.errorType == Unopened {
return fmt.Sprintf(unopenedFmt, string(e.rune), e.position)
} else if e.errorType == Unclosed {
return fmt.Sprintf(unclosedFmt, string(e.rune), e.position)
} else if e.wrapped != nil {
return e.wrapped.Error()
}
result := fmt.Sprintf(e.message, e.position)
if strings.HasSuffix(result, fmt.Sprintf(`%%!(EXTRA int=%d)`, e.position)) {
result = result[:strings.LastIndex(result, "%!(EXTRA int=")]
}
return result
}
func (e *splittingError) Unwrap() error {
return e.wrapped
}
func (e *splittingError) Type() SplittingErrorType {
return e.errorType
}
func (e *splittingError) Position() int {
return e.position
}
func (e *splittingError) Rune() rune {
return e.rune
}
func (e *splittingError) Enclosure() *Enclosure {
return e.enc
}
func (e *splittingError) Wrapped() error {
return e.wrapped
}
func asSplittingError(err error, pos int) SplittingError {
if err != nil {
if se, ok := err.(SplittingError); ok {
return se
} else {
return &splittingError{
errorType: Wrapped,
position: pos,
wrapped: err,
}
}
}
return nil
}
func NewOptionFailError(msg string, pos int, subPart SubPart) SplittingError {
if subPart != nil {
return &splittingError{
errorType: OptionFail,
position: subPart.StartPos(),
rune: subPart.StartRune(),
enc: subPart.Enclosure(),
message: msg,
}
}
return &splittingError{
errorType: OptionFail,
position: pos,
message: msg,
}
}