-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathswitch.go
69 lines (58 loc) · 2.16 KB
/
switch.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
package errorx
// NotRecognisedType is a synthetic type used in TypeSwitch, signifying a presence of non-nil error of some other type.
func NotRecognisedType() *Type { return notRecognisedType }
// CaseNoError is a synthetic trait used in TraitSwitch, signifying an absence of error.
func CaseNoError() Trait { return caseNoError }
// CaseNoTrait is a synthetic trait used in TraitSwitch, signifying a presence of non-nil error that lacks specified traits.
func CaseNoTrait() Trait { return caseNoTrait }
var (
notRecognisedType = syntheticErrors.NewType("non.recognised")
caseNoError = RegisterTrait("synthetic.no.error")
caseNoTrait = RegisterTrait("synthetic.no.trait")
)
// TypeSwitch is used to perform a switch around the type of an error.
// For nil errors, returns nil.
// For error types not in the 'types' list, including non-errorx errors, NotRecognisedType() is returned.
// It is safe to treat NotRecognisedType() as 'any other type of not-nil error' case.
// The effect is equivalent to a series of IsOfType() checks.
//
// NB: if more than one provided types matches the error, the first match in the providers list is recognised.
func TypeSwitch(err error, types ...*Type) *Type {
typed := Cast(err)
switch {
case err == nil:
return nil
case typed == nil:
return NotRecognisedType()
default:
for _, t := range types {
if typed.IsOfType(t) {
return t
}
}
return NotRecognisedType()
}
}
// TraitSwitch is used to perform a switch around the trait of an error.
// For nil errors, returns CaseNoError().
// For error types that lack any of the provided traits, including non-errorx errors, CaseNoTrait() is returned.
// It is safe to treat CaseNoTrait() as 'any other kind of not-nil error' case.
// The effect is equivalent to a series of HasTrait() checks.
//
// NB: if more than one provided types matches the error, the first match in the providers list is recognised.
func TraitSwitch(err error, traits ...Trait) Trait {
typed := Cast(err)
switch {
case err == nil:
return CaseNoError()
case typed == nil:
return CaseNoTrait()
default:
for _, t := range traits {
if typed.HasTrait(t) {
return t
}
}
return CaseNoTrait()
}
}