-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patherrors.go
58 lines (50 loc) · 1.2 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
package constraints
import "errors"
// An Error is a specialized error which describes constraint violation(s).
type Error[
ValueT any,
] interface {
error
ViolatedConstraint() Constraint[ValueT]
}
// ViolationError creates a new constraint violation error.
func ViolationError[
ValueT any,
](c Constraint[ValueT]) Error[ValueT] {
return &requirementError[ValueT]{c}
}
// ViolatedConstraintFromError attempts to extract violated Constraint
// from an error.
func ViolatedConstraintFromError[
ValueT any,
](err error) Constraint[ValueT] {
if err != nil {
if e, ok := err.(Error[ValueT]); ok {
return e.ViolatedConstraint()
}
return ViolatedConstraintFromError[ValueT](errors.Unwrap(err))
}
return nil
}
var (
_ Error[any] = &requirementError[any]{}
)
type requirementError[ValueT any] struct {
violated Constraint[ValueT]
}
func (e *requirementError[ValueT]) Error() string {
if e != nil {
if c := e.violated; c != nil {
return "required to be " +
c.ConstraintDescription()
}
return "constraint violation: <undefined>"
}
return "unknown constraint violation"
}
func (e *requirementError[ValueT]) ViolatedConstraint() Constraint[ValueT] {
if e != nil {
return e.violated
}
return nil
}