1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465openMiscopenSexplib.StdmoduleCo=CohttpmoduleRock=RockmoduleRoute=RouteopenRocktype'at=(Route.t*'a)Queue.tarray[@@derivingsexp]letcreate()=Array.init7(fun_->Queue.create())letint_of_meth=function|`GET->0|`POST->1|`PUT->2|`DELETE->3|`HEAD->4|`PATCH->5|`OPTIONS->6|_->failwith"non standard http verbs not supported"letgettmeth=t.(int_of_methmeth)letaddt~route~meth~action=Queue.push(route,action)t.(int_of_methmeth)(** finds matching endpoint and returns it with the parsed list of
parameters *)letmatching_endpointendpointsmethuri=letendpoints=getendpointsmethinendpoints|>Queue.find_map~f:(funep->uri|>Route.match_url(fstep)|>Option.map~f:(funp->(ep,p)))moduleEnv=structletkey:Route.matchesHmap0.key=Hmap0.Key.create("path_params",[%sexp_of:Route.matches])end(* not param_exn since if the endpoint was selected it's likely that
the parameter is already there *)letparamreqparam=let{Route.params;_}=Hmap0.find_exnEnv.key(Request.envreq)inList.assocparamparamsletsplatreq=Hmap0.find_exnEnv.key(Request.envreq)|>Route.splat(* takes a list of endpoints and a default handler. calls an endpoint
if a match is found. otherwise calls the handler *)letmendpoints=letfilterdefaultreq=leturl=req|>Request.uri|>Uri.pathinmatchmatching_endpointendpoints(Request.methreq)urlwith|None->defaultreq|Some(endpoint,params)->beginletenv_with_params=Hmap0.addEnv.keyparams(Request.envreq)in(sndendpoint){reqwithRequest.env=env_with_params}endinRock.Middleware.create~name:"Router"~filter