@@ -9,16 +9,12 @@ import Prelude.Compat
10import Data.Function
10import Data.Function
14import Data.Map
12import Data.Map
16import qualified Data.Map as M
14import qualified Data.Map as M
17import Data.Text
15import Data.Text
19import qualified Data.Text as T
17import qualified Data.Text as T
22import Network.Wai
18import Network.Wai
23 (Response, pathInfo)
19 (Response, pathInfo)
24import Servant.Server.Internal.ErrorFormatter
20import Servant.Server.Internal.ErrorFormatter
@@ -28,18 +24,6 @@ import Servant.Server.Internal.ServerError
29type Router env = Router' env RoutingApplication
25type Router env = Router' env RoutingApplication
31−data CaptureHint = CaptureHint
32− { captureName :: Text
33− , captureType :: TypeRep
37−toCaptureTag :: CaptureHint -> Text
38−toCaptureTag hint = captureName hint <> "::" <> (T.pack . show) (captureType hint)
40−toCaptureTags :: [CaptureHint] -> Text
41−toCaptureTags hints = "<" <> T.intercalate "|" (map toCaptureTag hints) <> ">"
43-- | Internal representation of a router.
27-- | Internal representation of a router.
45-- The first argument describes an environment type that is
29-- The first argument describes an environment type that is
@@ -52,10 +36,10 @@ data Router' env a =
52 -- ^ the map contains routers for subpaths (first path component used
36 -- ^ the map contains routers for subpaths (first path component used
53 -- for lookup and removed afterwards), the list contains handlers
37 -- for lookup and removed afterwards), the list contains handlers
54 -- for the empty path, to be tried in order
38 -- for the empty path, to be tried in order
55− | CaptureRouter [CaptureHint] (Router' (Text, env) a)
39+ | CaptureRouter (Router' (Text, env) a)
56 -- ^ first path component is passed to the child router in its
40 -- ^ first path component is passed to the child router in its
57 -- environment and removed afterwards
41 -- environment and removed afterwards
58− | CaptureAllRouter [CaptureHint] (Router' ([Text], env) a)
42+ | CaptureAllRouter (Router' ([Text], env) a)
59 -- ^ all path components are passed to the child router in its
43 -- ^ all path components are passed to the child router in its
60 -- environment and are removed afterwards
44 -- environment and are removed afterwards
61 | RawRouter (env -> a)
45 | RawRouter (env -> a)
@@ -85,8 +69,8 @@ leafRouter l = StaticRouter M.empty [l]
85choice :: Router' env a -> Router' env a -> Router' env a
69choice :: Router' env a -> Router' env a -> Router' env a
86choice (StaticRouter table1 ls1) (StaticRouter table2 ls2) =
70choice (StaticRouter table1 ls1) (StaticRouter table2 ls2) =
87 StaticRouter (M.unionWith choice table1 table2) (ls1 ++ ls2)
71 StaticRouter (M.unionWith choice table1 table2) (ls1 ++ ls2)
88−choice (CaptureRouter hints1 router1) (CaptureRouter hints2 router2) =
72+choice (CaptureRouter router1) (CaptureRouter router2) =
89− CaptureRouter (nub $ hints1 ++ hints2) (choice router1 router2)
73+ CaptureRouter (choice router1 router2)
90choice router1 (Choice router2 router3) = Choice (choice router1 router2) router3
74choice router1 (Choice router2 router3) = Choice (choice router1 router2) router3
91choice router1 router2 = Choice router1 router2
75choice router1 router2 = Choice router1 router2
@@ -100,7 +84,7 @@ choice router1 router2 = Choice router1 router2
101data RouterStructure =
85data RouterStructure =
102 StaticRouterStructure (Map Text RouterStructure) Int
86 StaticRouterStructure (Map Text RouterStructure) Int
103− | CaptureRouterStructure [CaptureHint] RouterStructure
87+ | CaptureRouterStructure RouterStructure
104 | RawRouterStructure
88 | RawRouterStructure
105 | ChoiceStructure RouterStructure RouterStructure
89 | ChoiceStructure RouterStructure RouterStructure
106 deriving (Eq, Show)
90 deriving (Eq, Show)
@@ -114,11 +98,11 @@ data RouterStructure =
114routerStructure :: Router' env a -> RouterStructure
98routerStructure :: Router' env a -> RouterStructure
115routerStructure (StaticRouter m ls) =
99routerStructure (StaticRouter m ls) =
116 StaticRouterStructure (fmap routerStructure m) (length ls)
100 StaticRouterStructure (fmap routerStructure m) (length ls)
117−routerStructure (CaptureRouter hints router) =
101+routerStructure (CaptureRouter router) =
118− CaptureRouterStructure hints $
102+ CaptureRouterStructure $
119 routerStructure router
103 routerStructure router
120−routerStructure (CaptureAllRouter hints router) =
104+routerStructure (CaptureAllRouter router) =
121− CaptureRouterStructure hints $
105+ CaptureRouterStructure $
122 routerStructure router
106 routerStructure router
123routerStructure (RawRouter _) =
107routerStructure (RawRouter _) =
124 RawRouterStructure
108 RawRouterStructure
@@ -130,8 +114,8 @@ routerStructure (Choice r1 r2) =
130-- | Compare the structure of two routers.
114-- | Compare the structure of two routers.
132sameStructure :: Router' env a -> Router' env b -> Bool
116sameStructure :: Router' env a -> Router' env b -> Bool
133−sameStructure router1 router2 =
117+sameStructure r1 r2 =
134− routerStructure router1 == routerStructure router2
118+ routerStructure r1 == routerStructure r2
136-- | Provide a textual representation of the
120-- | Provide a textual representation of the
137-- structure of a router.
121-- structure of a router.
@@ -142,8 +126,7 @@ routerLayout router =
143 mkRouterLayout :: Bool -> RouterStructure -> [Text]
127 mkRouterLayout :: Bool -> RouterStructure -> [Text]
144 mkRouterLayout c (StaticRouterStructure m n) = mkSubTrees c (M.toList m) n
128 mkRouterLayout c (StaticRouterStructure m n) = mkSubTrees c (M.toList m) n
145− mkRouterLayout c (CaptureRouterStructure hints r) =
129+ mkRouterLayout c (CaptureRouterStructure r) = mkSubTree c "<capture>" (mkRouterLayout False r)
146− mkSubTree c (toCaptureTags hints) (mkRouterLayout False r)
147 mkRouterLayout c RawRouterStructure =
130 mkRouterLayout c RawRouterStructure =
148 if c then ["├─ <raw>"] else ["└─ <raw>"]
131 if c then ["├─ <raw>"] else ["└─ <raw>"]
149 mkRouterLayout c (ChoiceStructure r1 r2) =
132 mkRouterLayout c (ChoiceStructure r1 r2) =
@@ -186,7 +169,7 @@ runRouterEnv fmt router env request respond =
186 -> let request' = request { pathInfo = rest }
169 -> let request' = request { pathInfo = rest }
187 in runRouterEnv fmt router' env request' respond
170 in runRouterEnv fmt router' env request' respond
188 _ -> respond $ Fail $ fmt request
171 _ -> respond $ Fail $ fmt request
189− CaptureRouter _ router' ->
172+ CaptureRouter router' ->
190 case pathInfo request of
173 case pathInfo request of
191 [] -> respond $ Fail $ fmt request
174 [] -> respond $ Fail $ fmt request
192 -- This case is to handle trailing slashes.
175 -- This case is to handle trailing slashes.
@@ -194,7 +177,7 @@ runRouterEnv fmt router env request respond =
194 first : rest
177 first : rest
195 -> let request' = request { pathInfo = rest }
178 -> let request' = request { pathInfo = rest }
196 in runRouterEnv fmt router' (first, env) request' respond
179 in runRouterEnv fmt router' (first, env) request' respond
197− CaptureAllRouter _ router' ->
180+ CaptureAllRouter router' ->
198 let segments = pathInfo request
181 let segments = pathInfo request
199 request' = request { pathInfo = [] }
182 request' = request { pathInfo = [] }
200 in runRouterEnv fmt router' (segments, env) request' respond
183 in runRouterEnv fmt router' (segments, env) request' respond