Skip to content

Commit

Permalink
前缀匹配
Browse files Browse the repository at this point in the history
  • Loading branch information
vm-001 committed Dec 16, 2023
1 parent 1c13ab1 commit 9357f0d
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 37 deletions.
15 changes: 15 additions & 0 deletions src/resty/parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ local STATES = {
none = 0,
finish = 1,
colon = 2,
asterisk = 3
}

function Parser.new(path)
Expand All @@ -28,6 +29,9 @@ function Parser.new(path)
end

-- /info/:user/project/:sub -> ["/info/", ":user", "/project/", ":sub"]
-- /api/v1/pay/*
-- /api/v1/pay/*path

-- /users/:id/xxx.*

function Parser.next(self)
Expand All @@ -52,6 +56,15 @@ function Parser.next(self)
print("return: ", sub(self.path, anchor, self.pos - 1))
end
return sub(self.path, anchor, self.pos - 1)
elseif c == BYTE_ASTERISK then
self.state = STATES.asterisk
local anchor = self.anchor
self.anchor = self.pos
-- TODO 下一次进入的时候还是重复的
if debug then
print("return: ", sub(self.path, anchor, self.pos - 1))
end
return sub(self.path, anchor, self.pos - 1)
end
elseif self.state == STATES.colon then
if c == BYTE_SLASH then
Expand All @@ -63,6 +76,8 @@ function Parser.next(self)
end
return sub(self.path, anchor, self.pos - 1)
end
elseif self.state == STATES.asterisk then
-- do nothing
end
self.pos = self.pos + 1
end
Expand Down
29 changes: 0 additions & 29 deletions src/resty/parser_test.lua

This file was deleted.

3 changes: 3 additions & 0 deletions src/resty/router.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ end
--
function Router:match(path, ctx)
ctx = ctx or EMPTY
if ctx.matched then
clear_table(ctx.matched)
end
-- dirty Implementation
local routes = self.static[path]
if routes then
Expand Down
7 changes: 4 additions & 3 deletions src/resty/sample.lua
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,13 @@ local function test_example()
local radix = require("router-tree")
local rx = radix.new({
{
paths = {"/name/:name/id/:id"},
paths = {"/name/*name"},
metadata = "metadata /name",
},
})
local ctx = { matched = {} }
print(rx:match("/name/json/id/1", ctx))

local ctx = {matched = {}}
local handler = rx:match("/name/", ctx)
print(inspect(ctx))
end

Expand Down
43 changes: 38 additions & 5 deletions src/resty/trie.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ local clear_table = utils.clear_table
local EMPTY = {}
local BYTE_SLASH = byte("/")
local BYTE_COLON = byte(":")
local BYTE_ASTERISK = byte("*")


local TrieNode = {}
Expand All @@ -25,6 +26,7 @@ local TYPES = {
STATIC = 0,
ROOT = 1,
PARAM = 2,
CATCH_ALL = 3,
}

local debug = true
Expand Down Expand Up @@ -55,11 +57,12 @@ local function insert_child(node, path, value)
--print(token)
node.path = token
node.path_n = #token
node.type = TYPES.STATIC
if byte(token) == BYTE_COLON then
-- wildcard
node.type = TYPES.PARAM
else
node.type = TYPES.STATIC
elseif byte(token) == BYTE_ASTERISK then
node.type = TYPES.CATCH_ALL
end
token = parser:next()
if token then
Expand Down Expand Up @@ -142,9 +145,6 @@ end
local paths = {}

function TrieNode:get(path, ctx)
if path == "/name/json/id/1" then
utils.breakpoint()
end
local paths_i = 1
clear_table(paths)
while true do
Expand Down Expand Up @@ -211,6 +211,24 @@ function TrieNode:get(path, ctx)
end
return self.value
end

elseif self.type == TYPES.CATCH_ALL then
-- 前缀匹配
if self.value then
paths[paths_i] = self.path
paths_i = paths_i + 1
if ctx and ctx.matched then
local param_name = sub(self.path, 2)
if #param_name == 0 then
param_name = ":ext"
end
ctx.matched[param_name] = path
ctx.matched["_path"] = table.concat(paths)
end
return self.value
end
else
error("???")
end
end
elseif path == prefix then
Expand All @@ -220,6 +238,21 @@ function TrieNode:get(path, ctx)
end
return self.value
end

for _, child in ipairs(self.children or EMPTY) do
if child.type == TYPES.CATCH_ALL then
if ctx and ctx.matched then
local param_name = sub(child.path, 2)
if #param_name == 0 then
param_name = ":ext"
end
ctx.matched[param_name] = ""
paths[paths_i] = child.path
ctx.matched["_path"] = table.concat(paths)
end
return child.value
end
end
end

return nil
Expand Down

0 comments on commit 9357f0d

Please sign in to comment.