Skip to content

Commit

Permalink
feat: support status constants
Browse files Browse the repository at this point in the history
  • Loading branch information
crhntr committed Aug 30, 2024
1 parent 4502441 commit 85d0d68
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 7 deletions.
10 changes: 10 additions & 0 deletions internal/source/go.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,16 @@ var httpCodes = map[int]string{
http.StatusNetworkAuthenticationRequired: "StatusNetworkAuthenticationRequired",
}

func HTTPStatusName(name string) (int, error) {
n := strings.TrimPrefix(name, "http.")
for code, constName := range httpCodes {
if constName == n {
return code, nil
}
}
return 0, fmt.Errorf("unknown %s", name)
}

func HTTPStatusCode(pkg string, n int) ast.Expr {
ident, ok := httpCodes[n]
if !ok {
Expand Down
18 changes: 13 additions & 5 deletions name.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,19 @@ func newTemplate(in string) (TemplateName, error, bool) {
statusCode: http.StatusOK,
}
if s := matches[templateNameMux.SubexpIndex("code")]; s != "" {
code, err := strconv.Atoi(strings.TrimSpace(s))
if err != nil {
return TemplateName{}, fmt.Errorf("failed to parse status code: %w", err), true
if strings.HasPrefix(s, "http.Status") {
code, err := source.HTTPStatusName(s)
if err != nil {
return TemplateName{}, fmt.Errorf("failed to parse status code: %w", err), true
}
p.statusCode = code
} else {
code, err := strconv.Atoi(strings.TrimSpace(s))
if err != nil {
return TemplateName{}, fmt.Errorf("failed to parse status code: %w", err), true
}
p.statusCode = code
}
p.statusCode = code
}

switch p.method {
Expand All @@ -96,7 +104,7 @@ func newTemplate(in string) (TemplateName, error, bool) {

var (
pathSegmentPattern = regexp.MustCompile(`/\{([^}]*)}`)
templateNameMux = regexp.MustCompile(`^(?P<endpoint>(((?P<method>[A-Z]+)\s+)?)(?P<host>([^/])*)(?P<path>(/(\S)*)))(?P<code>\s\d+)?(?P<handler>\PL+.*\(.*\))?$`)
templateNameMux = regexp.MustCompile(`^(?P<endpoint>(((?P<method>[A-Z]+)\s+)?)(?P<host>([^/])*)(?P<path>(/(\S)*)))(\s+(?P<code>(\d|http\.Status)\S+))?(?P<handler>.*)?$`)
)

func (def TemplateName) parsePathValueNames() ([]string, error) {
Expand Down
16 changes: 16 additions & 0 deletions name_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,22 @@ func TestNewTemplateName(t *testing.T) {
assert.Equal(t, http.StatusAccepted, pat.statusCode)
},
},
{
Name: "with status code constant",
In: "POST / http.StatusTeapot F()",
ExpMatch: true,
TemplateName: func(t *testing.T, pat TemplateName) {
assert.Equal(t, http.StatusTeapot, pat.statusCode)
},
},
{
Name: "with status code constant",
In: "POST / http.StatusBANANA F()",
ExpMatch: true,
Error: func(t *testing.T, err error) {
assert.ErrorContains(t, err, "failed to parse status code: unknown http.StatusBANANA")
},
},
} {
t.Run(tt.Name, func(t *testing.T) {
pat, err, match := NewTemplateName(tt.In)
Expand Down
11 changes: 9 additions & 2 deletions name_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,19 @@ func TestPattern_parseHandler(t *testing.T) {
{
Name: "float64 as handler",
In: "POST / 1.2",
ExpMatch: false,
ExpMatch: true,
ExpErr: `failed to parse status code: strconv.Atoi: parsing "1.2": invalid syntax`,
},
{
Name: "status constant",
In: "POST / http.StatusOK",
ExpMatch: true,
},
{
Name: "not an expression",
In: "GET / package main",
ExpMatch: false,
ExpMatch: true,
ExpErr: "failed to parse handler expression: ",
},
{
Name: "function literal",
Expand Down

0 comments on commit 85d0d68

Please sign in to comment.