So, I redid the methodology for parsing the tree. But I realized an obstacle that I am not sure how to overcome.
First of all, one thing I am trying very hard to achieve is to make this a drop in replacement for the Sanic router. Sanic will allow you to do something like this:
srouter = sanic.router.Router()
srouter.add("/foo/<id:int>", ["get"], 1)
srouter.add("/foo/<id:string>", ["get"], 2)
You can run this and see it works as expected.
class Request:
def __init__(self, path, method):
self.path = path
self.method = method
print(srouter.get(Request("/foo/1", "get")))
print(srouter.get(Request("/foo/abc", "get")))
Two routes have an identical path, but they have different regex. Therefore the Sanic router allows this.
The equivalent in Falcon does not work. This is not acceptable
frouter = falcon.routing.CompiledRouter()
frouter.add_route("/foo/{id:int}", method_map=["GET"], resource=1)
frouter.add_route("/foo/{id:uuid}", method_map=["GET"], resource=1)
The way the AST style routers work is that all dynamic variables are sort of the same. There is nothing to check or compare against. Later, after the route is found it can be cast to type.
Which seems like a roadblock for full compatibility.
Or is it?
Perhaps we can merge them with two optional casts, and it can try both. Of course the idea popped into my head after I started writing this…
I am going to leave the post anyway. Will report back.