-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoptions.go
More file actions
79 lines (67 loc) · 2.17 KB
/
options.go
File metadata and controls
79 lines (67 loc) · 2.17 KB
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
package errdecode
// Option sets an optional parameter for decoders.
type Option func(*Decoder)
// Message is used to translate the message of a matched, decoded error value.
//
// This is particular useful for integrating transformations or performing
// key-based lookups, e.g., locale-based text or remote lookups.
func Message(t MessageTranslatorFunc) Option {
return func(d *Decoder) { d.msgTranslator = t }
}
// Encoder is used to provide an error classifier.
//
// It is most useful in scenarios where errors need to be checked in a variety
// of ways, e.g., custom error wrapping.
func Encoder(enc EncoderFunc) Option {
return func(d *Decoder) { d.encoder = enc }
}
// A mirror effect.
func defaultMessageTranslator(msg string) string {
return msg
}
// Returns the default encoder, which performs the following checks:
//
// 1. Compare the error value to classified error values
// 2. Pass the error value to classified matchers
//
// If any are true, the classification code and message are returned.
//
// In the case of an unclassified error, the zero values are used.
func newDefaultEncoder(rs []Rule) EncoderFunc {
idx := newRuleIndex(rs)
return func(err error) (int, string) {
if code, ok := idx.errToCode[err]; ok {
return code, idx.codeToMessage[code]
}
for code, matcher := range idx.codeToMatcher {
if isMatch := matcher(err); isMatch {
return code, idx.codeToMessage[code]
}
}
return 0, "" // unclassified error
}
}
// ruleIndex represents various convenience maps derived from a rules slice.
// It provides constant-time lookups for fields of importance.
type ruleIndex struct {
codeToMatcher map[int]MatcherFunc
codeToMessage map[int]string
errToCode map[error]int
}
// newRuleIndex create indexes from the provided rules.
func newRuleIndex(rs []Rule) *ruleIndex {
codeToMatcher := make(map[int]MatcherFunc)
codeToMessage := make(map[int]string)
errToCode := make(map[error]int)
for _, rule := range rs {
code := rule.Code
codeToMessage[code] = rule.Message
if rule.Match != nil {
codeToMatcher[code] = rule.Match
}
for _, e := range rule.Errors {
errToCode[e] = code
}
}
return &ruleIndex{codeToMatcher, codeToMessage, errToCode}
}