diff --git a/node.go b/node.go index 5aab30a..5055739 100644 --- a/node.go +++ b/node.go @@ -5,7 +5,7 @@ import "strings" // Node types const ( separator = '/' - parameter = ':' + parameter = '[' wildcard = '*' ) @@ -119,15 +119,21 @@ func (node *Node[T]) append(path string, data T) { // If we're directly in front of a parameter, // add a parameter node. if paramStart == 0 { - paramEnd := strings.IndexByte(path, separator) - + paramEnd := strings.IndexByte(path[1:], ']') if paramEnd == -1 { paramEnd = len(path) + } else { + paramEnd = paramEnd + 1 // Account for the offset from path[1:] + } + + nextSep := strings.IndexByte(path[paramEnd+1:], separator) + if nextSep == -1 { + nextSep = len(path[paramEnd+1:]) } child := &Node[T]{ - prefix: path[1:paramEnd], - kind: path[paramStart], + prefix: path[1:paramEnd], // Exclude the opening '[' + kind: parameter, } switch child.kind { @@ -135,7 +141,7 @@ func (node *Node[T]) append(path string, data T) { child.addTrailingSlash(data) node.parameter = child node = child - path = path[paramEnd:] + path = path[paramEnd+nextSep+1:] continue case wildcard: diff --git a/tests/blog.txt b/tests/blog.txt index 755965f..f0d928f 100644 --- a/tests/blog.txt +++ b/tests/blog.txt @@ -1,4 +1,4 @@ GET / -GET /:slug +GET /[slug] GET /tags -GET /tag/:tag \ No newline at end of file +GET /tag/[tag] \ No newline at end of file diff --git a/tests/github.txt b/tests/github.txt index fc85456..d22ed36 100644 --- a/tests/github.txt +++ b/tests/github.txt @@ -1,203 +1,203 @@ GET /authorizations -GET /authorizations/:id +GET /authorizations/[id] POST /authorizations -DELETE /authorizations/:id -GET /applications/:client_id/tokens/:access_token -DELETE /applications/:client_id/tokens -DELETE /applications/:client_id/tokens/:access_token +DELETE /authorizations/[id] +GET /applications/[client_id]/tokens/[access_token] +DELETE /applications/[client_id]/tokens +DELETE /applications/[client_id]/tokens/[access_token] GET /events -GET /repos/:owner/:repo/events -GET /networks/:owner/:repo/events -GET /orgs/:org/events -GET /users/:user/received_events -GET /users/:user/received_events/public -GET /users/:user/events -GET /users/:user/events/public -GET /users/:user/events/orgs/:org +GET /repos/[owner]/[repo]/events +GET /networks/[owner]/[repo]/events +GET /orgs/[org]/events +GET /users/[user]/received_events +GET /users/[user]/received_events/public +GET /users/[user]/events +GET /users/[user]/events/public +GET /users/[user]/events/orgs/[org] GET /feeds GET /notifications -GET /repos/:owner/:repo/notifications +GET /repos/[owner]/[repo]/notifications PUT /notifications -PUT /repos/:owner/:repo/notifications -GET /notifications/threads/:id -GET /notifications/threads/:id/subscription -PUT /notifications/threads/:id/subscription -DELETE /notifications/threads/:id/subscription -GET /repos/:owner/:repo/stargazers -GET /users/:user/starred +PUT /repos/[owner]/[repo]/notifications +GET /notifications/threads/[id] +GET /notifications/threads/[id]/subscription +PUT /notifications/threads/[id]/subscription +DELETE /notifications/threads/[id]/subscription +GET /repos/[owner]/[repo]/stargazers +GET /users/[user]/starred GET /user/starred -GET /user/starred/:owner/:repo -PUT /user/starred/:owner/:repo -DELETE /user/starred/:owner/:repo -GET /repos/:owner/:repo/subscribers -GET /users/:user/subscriptions +GET /user/starred/[owner]/[repo] +PUT /user/starred/[owner]/[repo] +DELETE /user/starred/[owner]/[repo] +GET /repos/[owner]/[repo]/subscribers +GET /users/[user]/subscriptions GET /user/subscriptions -GET /repos/:owner/:repo/subscription -PUT /repos/:owner/:repo/subscription -DELETE /repos/:owner/:repo/subscription -GET /user/subscriptions/:owner/:repo -PUT /user/subscriptions/:owner/:repo -DELETE /user/subscriptions/:owner/:repo -GET /users/:user/gists +GET /repos/[owner]/[repo]/subscription +PUT /repos/[owner]/[repo]/subscription +DELETE /repos/[owner]/[repo]/subscription +GET /user/subscriptions/[owner]/[repo] +PUT /user/subscriptions/[owner]/[repo] +DELETE /user/subscriptions/[owner]/[repo] +GET /users/[user]/gists GET /gists -GET /gists/:id +GET /gists/[id] POST /gists -PUT /gists/:id/star -DELETE /gists/:id/star -GET /gists/:id/star -POST /gists/:id/forks -DELETE /gists/:id -GET /repos/:owner/:repo/git/blobs/:sha -POST /repos/:owner/:repo/git/blobs -GET /repos/:owner/:repo/git/commits/:sha -POST /repos/:owner/:repo/git/commits -GET /repos/:owner/:repo/git/refs -POST /repos/:owner/:repo/git/refs -GET /repos/:owner/:repo/git/tags/:sha -POST /repos/:owner/:repo/git/tags -GET /repos/:owner/:repo/git/trees/:sha -POST /repos/:owner/:repo/git/trees +PUT /gists/[id]/star +DELETE /gists/[id]/star +GET /gists/[id]/star +POST /gists/[id]/forks +DELETE /gists/[id] +GET /repos/[owner]/[repo]/git/blobs/[sha] +POST /repos/[owner]/[repo]/git/blobs +GET /repos/[owner]/[repo]/git/commits/[sha] +POST /repos/[owner]/[repo]/git/commits +GET /repos/[owner]/[repo]/git/refs +POST /repos/[owner]/[repo]/git/refs +GET /repos/[owner]/[repo]/git/tags/[sha] +POST /repos/[owner]/[repo]/git/tags +GET /repos/[owner]/[repo]/git/trees/[sha] +POST /repos/[owner]/[repo]/git/trees GET /issues GET /user/issues -GET /orgs/:org/issues -GET /repos/:owner/:repo/issues -GET /repos/:owner/:repo/issues/:number -POST /repos/:owner/:repo/issues -GET /repos/:owner/:repo/assignees -GET /repos/:owner/:repo/assignees/:assignee -GET /repos/:owner/:repo/issues/:number/comments -POST /repos/:owner/:repo/issues/:number/comments -GET /repos/:owner/:repo/issues/:number/events -GET /repos/:owner/:repo/labels -GET /repos/:owner/:repo/labels/:name -POST /repos/:owner/:repo/labels -DELETE /repos/:owner/:repo/labels/:name -GET /repos/:owner/:repo/issues/:number/labels -POST /repos/:owner/:repo/issues/:number/labels -DELETE /repos/:owner/:repo/issues/:number/labels/:name -PUT /repos/:owner/:repo/issues/:number/labels -DELETE /repos/:owner/:repo/issues/:number/labels -GET /repos/:owner/:repo/milestones/:number/labels -GET /repos/:owner/:repo/milestones -GET /repos/:owner/:repo/milestones/:number -POST /repos/:owner/:repo/milestones -DELETE /repos/:owner/:repo/milestones/:number +GET /orgs/[org]/issues +GET /repos/[owner]/[repo]/issues +GET /repos/[owner]/[repo]/issues/[number] +POST /repos/[owner]/[repo]/issues +GET /repos/[owner]/[repo]/assignees +GET /repos/[owner]/[repo]/assignees/[assignee] +GET /repos/[owner]/[repo]/issues/[number]/comments +POST /repos/[owner]/[repo]/issues/[number]/comments +GET /repos/[owner]/[repo]/issues/[number]/events +GET /repos/[owner]/[repo]/labels +GET /repos/[owner]/[repo]/labels/[name] +POST /repos/[owner]/[repo]/labels +DELETE /repos/[owner]/[repo]/labels/[name] +GET /repos/[owner]/[repo]/issues/[number]/labels +POST /repos/[owner]/[repo]/issues/[number]/labels +DELETE /repos/[owner]/[repo]/issues/[number]/labels/[name] +PUT /repos/[owner]/[repo]/issues/[number]/labels +DELETE /repos/[owner]/[repo]/issues/[number]/labels +GET /repos/[owner]/[repo]/milestones/[number]/labels +GET /repos/[owner]/[repo]/milestones +GET /repos/[owner]/[repo]/milestones/[number] +POST /repos/[owner]/[repo]/milestones +DELETE /repos/[owner]/[repo]/milestones/[number] GET /emojis GET /gitignore/templates -GET /gitignore/templates/:name +GET /gitignore/templates/[name] POST /markdown POST /markdown/raw GET /meta GET /rate_limit -GET /users/:user/orgs +GET /users/[user]/orgs GET /user/orgs -GET /orgs/:org -GET /orgs/:org/members -GET /orgs/:org/members/:user -DELETE /orgs/:org/members/:user -GET /orgs/:org/public_members -GET /orgs/:org/public_members/:user -PUT /orgs/:org/public_members/:user -DELETE /orgs/:org/public_members/:user -GET /orgs/:org/teams -GET /teams/:id -POST /orgs/:org/teams -DELETE /teams/:id -GET /teams/:id/members -GET /teams/:id/members/:user -PUT /teams/:id/members/:user -DELETE /teams/:id/members/:user -GET /teams/:id/repos -GET /teams/:id/repos/:owner/:repo -PUT /teams/:id/repos/:owner/:repo -DELETE /teams/:id/repos/:owner/:repo +GET /orgs/[org] +GET /orgs/[org]/members +GET /orgs/[org]/members/[user] +DELETE /orgs/[org]/members/[user] +GET /orgs/[org]/public_members +GET /orgs/[org]/public_members/[user] +PUT /orgs/[org]/public_members/[user] +DELETE /orgs/[org]/public_members/[user] +GET /orgs/[org]/teams +GET /teams/[id] +POST /orgs/[org]/teams +DELETE /teams/[id] +GET /teams/[id]/members +GET /teams/[id]/members/[user] +PUT /teams/[id]/members/[user] +DELETE /teams/[id]/members/[user] +GET /teams/[id]/repos +GET /teams/[id]/repos/[owner]/[repo] +PUT /teams/[id]/repos/[owner]/[repo] +DELETE /teams/[id]/repos/[owner]/[repo] GET /user/teams -GET /repos/:owner/:repo/pulls -GET /repos/:owner/:repo/pulls/:number -POST /repos/:owner/:repo/pulls -GET /repos/:owner/:repo/pulls/:number/commits -GET /repos/:owner/:repo/pulls/:number/files -GET /repos/:owner/:repo/pulls/:number/merge -PUT /repos/:owner/:repo/pulls/:number/merge -GET /repos/:owner/:repo/pulls/:number/comments -PUT /repos/:owner/:repo/pulls/:number/comments +GET /repos/[owner]/[repo]/pulls +GET /repos/[owner]/[repo]/pulls/[number] +POST /repos/[owner]/[repo]/pulls +GET /repos/[owner]/[repo]/pulls/[number]/commits +GET /repos/[owner]/[repo]/pulls/[number]/files +GET /repos/[owner]/[repo]/pulls/[number]/merge +PUT /repos/[owner]/[repo]/pulls/[number]/merge +GET /repos/[owner]/[repo]/pulls/[number]/comments +PUT /repos/[owner]/[repo]/pulls/[number]/comments GET /user/repos -GET /users/:user/repos -GET /orgs/:org/repos +GET /users/[user]/repos +GET /orgs/[org]/repos GET /repositories POST /user/repos -POST /orgs/:org/repos -GET /repos/:owner/:repo -GET /repos/:owner/:repo/contributors -GET /repos/:owner/:repo/languages -GET /repos/:owner/:repo/teams -GET /repos/:owner/:repo/tags -GET /repos/:owner/:repo/branches -GET /repos/:owner/:repo/branches/:branch -DELETE /repos/:owner/:repo -GET /repos/:owner/:repo/collaborators -GET /repos/:owner/:repo/collaborators/:user -PUT /repos/:owner/:repo/collaborators/:user -DELETE /repos/:owner/:repo/collaborators/:user -GET /repos/:owner/:repo/comments -GET /repos/:owner/:repo/commits/:sha/comments -POST /repos/:owner/:repo/commits/:sha/comments -GET /repos/:owner/:repo/comments/:id -DELETE /repos/:owner/:repo/comments/:id -GET /repos/:owner/:repo/commits -GET /repos/:owner/:repo/commits/:sha -GET /repos/:owner/:repo/readme -GET /repos/:owner/:repo/keys -GET /repos/:owner/:repo/keys/:id -POST /repos/:owner/:repo/keys -DELETE /repos/:owner/:repo/keys/:id -GET /repos/:owner/:repo/downloads -GET /repos/:owner/:repo/downloads/:id -DELETE /repos/:owner/:repo/downloads/:id -GET /repos/:owner/:repo/forks -POST /repos/:owner/:repo/forks -GET /repos/:owner/:repo/hooks -GET /repos/:owner/:repo/hooks/:id -POST /repos/:owner/:repo/hooks -POST /repos/:owner/:repo/hooks/:id/tests -DELETE /repos/:owner/:repo/hooks/:id -POST /repos/:owner/:repo/merges -GET /repos/:owner/:repo/releases -GET /repos/:owner/:repo/releases/:id -POST /repos/:owner/:repo/releases -DELETE /repos/:owner/:repo/releases/:id -GET /repos/:owner/:repo/releases/:id/assets -GET /repos/:owner/:repo/stats/contributors -GET /repos/:owner/:repo/stats/commit_activity -GET /repos/:owner/:repo/stats/code_frequency -GET /repos/:owner/:repo/stats/participation -GET /repos/:owner/:repo/stats/punch_card -GET /repos/:owner/:repo/statuses/:ref -POST /repos/:owner/:repo/statuses/:ref +POST /orgs/[org]/repos +GET /repos/[owner]/[repo] +GET /repos/[owner]/[repo]/contributors +GET /repos/[owner]/[repo]/languages +GET /repos/[owner]/[repo]/teams +GET /repos/[owner]/[repo]/tags +GET /repos/[owner]/[repo]/branches +GET /repos/[owner]/[repo]/branches/[branch] +DELETE /repos/[owner]/[repo] +GET /repos/[owner]/[repo]/collaborators +GET /repos/[owner]/[repo]/collaborators/[user] +PUT /repos/[owner]/[repo]/collaborators/[user] +DELETE /repos/[owner]/[repo]/collaborators/[user] +GET /repos/[owner]/[repo]/comments +GET /repos/[owner]/[repo]/commits/[sha]/comments +POST /repos/[owner]/[repo]/commits/[sha]/comments +GET /repos/[owner]/[repo]/comments/[id] +DELETE /repos/[owner]/[repo]/comments/[id] +GET /repos/[owner]/[repo]/commits +GET /repos/[owner]/[repo]/commits/[sha] +GET /repos/[owner]/[repo]/readme +GET /repos/[owner]/[repo]/keys +GET /repos/[owner]/[repo]/keys/[id] +POST /repos/[owner]/[repo]/keys +DELETE /repos/[owner]/[repo]/keys/[id] +GET /repos/[owner]/[repo]/downloads +GET /repos/[owner]/[repo]/downloads/[id] +DELETE /repos/[owner]/[repo]/downloads/[id] +GET /repos/[owner]/[repo]/forks +POST /repos/[owner]/[repo]/forks +GET /repos/[owner]/[repo]/hooks +GET /repos/[owner]/[repo]/hooks/[id] +POST /repos/[owner]/[repo]/hooks +POST /repos/[owner]/[repo]/hooks/[id]/tests +DELETE /repos/[owner]/[repo]/hooks/[id] +POST /repos/[owner]/[repo]/merges +GET /repos/[owner]/[repo]/releases +GET /repos/[owner]/[repo]/releases/[id] +POST /repos/[owner]/[repo]/releases +DELETE /repos/[owner]/[repo]/releases/[id] +GET /repos/[owner]/[repo]/releases/[id]/assets +GET /repos/[owner]/[repo]/stats/contributors +GET /repos/[owner]/[repo]/stats/commit_activity +GET /repos/[owner]/[repo]/stats/code_frequency +GET /repos/[owner]/[repo]/stats/participation +GET /repos/[owner]/[repo]/stats/punch_card +GET /repos/[owner]/[repo]/statuses/[ref] +POST /repos/[owner]/[repo]/statuses/[ref] GET /search/repositories GET /search/code GET /search/issues GET /search/users -GET /legacy/issues/search/:owner/:repository/:state/:keyword -GET /legacy/repos/search/:keyword -GET /legacy/user/search/:keyword -GET /legacy/user/email/:email -GET /users/:user +GET /legacy/issues/search/[owner]/[repository]/[state]/[keyword] +GET /legacy/repos/search/[keyword] +GET /legacy/user/search/[keyword] +GET /legacy/user/email/[email] +GET /users/[user] GET /user GET /users GET /user/emails POST /user/emails DELETE /user/emails -GET /users/:user/followers +GET /users/[user]/followers GET /user/followers -GET /users/:user/following +GET /users/[user]/following GET /user/following -GET /user/following/:user -GET /users/:user/following/:target_user -PUT /user/following/:user -DELETE /user/following/:user -GET /users/:user/keys +GET /user/following/[user] +GET /users/[user]/following/[target_user] +PUT /user/following/[user] +DELETE /user/following/[user] +GET /users/[user]/keys GET /user/keys -GET /user/keys/:id +GET /user/keys/[id] POST /user/keys -DELETE /user/keys/:id \ No newline at end of file +DELETE /user/keys/[id] \ No newline at end of file