-
Notifications
You must be signed in to change notification settings - Fork 232
/
range.go
91 lines (76 loc) · 2 KB
/
range.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
package errors
import (
"fmt"
)
var (
nextRangeStart = 1000
)
// Range creates a new error code range for a given module.
func Range(
module string,
defaultDetails string,
options ...RangeOption,
) *TemplateRange {
if nextRangeStart > 9999 {
// If we hit this, we need to increase the number of digits in the error code renderer
panic("too many error code ranges")
}
// Configure the range
cfg := &rangeConfig{
rangeSize: 100,
}
for _, c := range options {
c(cfg)
}
// Create the Range
rangeStart := nextRangeStart
nextRangeStart += cfg.rangeSize
return &TemplateRange{
module: module,
defaultDetails: defaultDetails,
nextErrorCode: rangeStart,
codeRangeEnd: nextRangeStart,
}
}
type rangeConfig struct {
rangeSize int
}
type RangeOption func(*rangeConfig)
// WithRangeSize sets the size of the range. The default is 100.
func WithRangeSize(size int) RangeOption {
return func(cfg *rangeConfig) {
cfg.rangeSize = size
}
}
// TemplateRange is a helper for creating a range of error codes for a given module
// and generating templates for those errors.
type TemplateRange struct {
module string
defaultDetails string
nextErrorCode int
codeRangeEnd int // Exclusive
}
// New creates a new template for an error in this range.
func (r *TemplateRange) New(title, summary string, options ...TemplateOption) Template {
return r.Newf(title, summary, options...)()
}
// Newf creates a function to return a template for an error in this range where the summary is a format string.
func (r *TemplateRange) Newf(title, summaryFmt string, options ...TemplateOption) func(summaryArgs ...any) Template {
if r.nextErrorCode >= r.codeRangeEnd {
panic("too many errors in range")
}
errorCode := r.nextErrorCode
r.nextErrorCode++
return func(summaryArgs ...any) Template {
tmp := Template{
Code: errorCode,
Title: title,
Summary: fmt.Sprintf(summaryFmt, summaryArgs...),
Detail: r.defaultDetails,
}
for _, o := range options {
o(&tmp)
}
return tmp
}
}