49 lines
1.8 KiB
Python
49 lines
1.8 KiB
Python
# / -> Exact("/")
|
|
# /foo -> Exact("/foo")
|
|
# /foo/ -> Exact("/foo/")
|
|
# /foo/bar -> Exact("/foo/bar")
|
|
# /foo/bar/{n} -> Exact("/foo/bar/"), Format("n")
|
|
# /foo/{n}/bar -> Exact("/foo/"), Format("n"), Exact("/bar")
|
|
# /foo{n:5}/bar -> Exact("/foo"), Format("n", minl=5, maxl=5), Exact("/bar")
|
|
# /foo/{m:1-}/{n:3-5}bar -> Exact("/foo/"), Format("m", minl=1, maxl=-1), Exact("/"), Format("n", minl=3, maxl=5), Exact("bar")
|
|
# /* -> Exact("/"), Format("_")
|
|
# /foo/*bar -> Exact("/foo/"), Format("_"), Exact("bar")
|
|
# /foo/*/bar -> Exact("/foo/"), Format("_"), Exact("/bar")
|
|
# /foo/**/bar -> Exact("/foo/"), Format("_", ignore_sep=True), Exact("/bar")
|
|
|
|
# ["foo", Format("m", minl=1, maxl=-1), [Format("n", minl=3, maxl=5), "bar"], "*"]
|
|
|
|
|
|
import ctypes
|
|
|
|
dll = ctypes.CDLL("./c_route.so")
|
|
dll.parse_route.restype = type("c_char_alloc", (ctypes.c_char_p,), {})
|
|
dll.free_parsed_route.argtypes = (ctypes.c_void_p,)
|
|
dll.free_parsed_route.restype = None
|
|
|
|
|
|
def compile_route(pattern: str) -> list[bytes]:
|
|
if pattern[0] != "/":
|
|
from app.exceptions import ParseError
|
|
raise ParseError("The first character in route pattern must be '/'.")
|
|
|
|
# res: list[str] = []
|
|
# for path in pattern[1:].split("/"):
|
|
# if (star_idx := path.find("*")) != -1:
|
|
# path = "".join((path[:star_idx], "{_}", path[star_idx + 1:]))
|
|
# if "{" not in path and "}" not in path and "*" not in path:
|
|
# res.append(path)
|
|
|
|
outlen = ctypes.c_size_t()
|
|
data = pattern[1:].encode()
|
|
ret = dll.parse_route(data, len(data), ctypes.byref(outlen))
|
|
res = ctypes.string_at(ret, outlen.value - 2).split(b"\x01")
|
|
dll.free_parsed_route(ret)
|
|
|
|
return res
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print(compile_route("/foo/{n:5}foo/bar/**/baz"))
|
|
print(compile_route("/"))
|