@@ -4,6 +4,7 @@
4{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7+{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE OverloadedStrings #-}
8{-# LANGUAGE OverloadedStrings #-}
8{-# LANGUAGE PolyKinds #-}
9{-# LANGUAGE PolyKinds #-}
9{-# LANGUAGE ScopedTypeVariables #-}
10{-# LANGUAGE ScopedTypeVariables #-}
@@ -68,11 +69,10 @@ import Servant.Server.Internal.RoutingApplication
68import Servant.Server.Internal.ServantErr
69import Servant.Server.Internal.ServantErr
71−class HasServer layout where
72+class HasServer layout config where
72 type ServerT layout (m :: * -> *) :: *
73 type ServerT layout (m :: * -> *) :: *
73− type HasConfig layout (c :: [*]) :: Constraint
75− route :: HasConfig layout config => Proxy layout -> Config config -> Delayed (Server layout) -> Router
75+ route :: Proxy layout -> Config config -> Delayed (Server layout) -> Router
77type Server layout = ServerT layout (ExceptT ServantErr IO)
77type Server layout = ServerT layout (ExceptT ServantErr IO)
@@ -89,10 +89,9 @@ type Server layout = ServerT layout (ExceptT ServantErr IO)
89-- > server = listAllBooks :<|> postBook
89-- > server = listAllBooks :<|> postBook
90-- > where listAllBooks = ...
90-- > where listAllBooks = ...
91-- > postBook book = ...
91-- > postBook book = ...
92−instance (HasServer a, HasServer b) => HasServer (a :<|> b) where
92+instance (HasServer a config, HasServer b config) => HasServer (a :<|> b) config where
94 type ServerT (a :<|> b) m = ServerT a m :<|> ServerT b m
94 type ServerT (a :<|> b) m = ServerT a m :<|> ServerT b m
95− type HasConfig (a :<|> b) c = (HasConfig a c, HasConfig b c)
97 route Proxy config server = choice (route pa config ((\ (a :<|> _) -> a) <$> server))
96 route Proxy config server = choice (route pa config ((\ (a :<|> _) -> a) <$> server))
98 (route pb config ((\ (_ :<|> b) -> b) <$> server))
97 (route pb config ((\ (_ :<|> b) -> b) <$> server))
@@ -119,12 +118,11 @@ captured _ = parseUrlPieceMaybe
119-- > server = getBook
118-- > server = getBook
120-- > where getBook :: Text -> ExceptT ServantErr IO Book
119-- > where getBook :: Text -> ExceptT ServantErr IO Book
121-- > getBook isbn = ...
120-- > getBook isbn = ...
122−instance (KnownSymbol capture, FromHttpApiData a, HasServer sublayout)
121+instance (KnownSymbol capture, FromHttpApiData a, HasServer sublayout config)
123− => HasServer (Capture capture a :> sublayout) where
122+ => HasServer (Capture capture a :> sublayout) config where
125 type ServerT (Capture capture a :> sublayout) m =
124 type ServerT (Capture capture a :> sublayout) m =
126 a -> ServerT sublayout m
125 a -> ServerT sublayout m
127− type HasConfig (Capture capture a :> sublayout) c = (HasConfig sublayout c)
129 route Proxy config d =
127 route Proxy config d =
130 DynamicRouter $ \ first ->
128 DynamicRouter $ \ first ->
@@ -198,10 +196,9 @@ methodRouterHeaders method proxy status action = LeafRouter route'
199instance OVERLAPPABLE_
197instance OVERLAPPABLE_
200 ( AllCTRender ctypes a, ReflectMethod method, KnownNat status
198 ( AllCTRender ctypes a, ReflectMethod method, KnownNat status
201− ) => HasServer (Verb method status ctypes a) where
199+ ) => HasServer (Verb method status ctypes a) config where
203 type ServerT (Verb method status ctypes a) m = m a
201 type ServerT (Verb method status ctypes a) m = m a
204− type HasConfig (Verb method status ctypes a) c = ()
206 route Proxy _ = methodRouter method (Proxy :: Proxy ctypes) status
203 route Proxy _ = methodRouter method (Proxy :: Proxy ctypes) status
207 where method = reflectMethod (Proxy :: Proxy method)
204 where method = reflectMethod (Proxy :: Proxy method)
@@ -210,10 +207,9 @@ instance OVERLAPPABLE_
210instance OVERLAPPING_
207instance OVERLAPPING_
211 ( AllCTRender ctypes a, ReflectMethod method, KnownNat status
208 ( AllCTRender ctypes a, ReflectMethod method, KnownNat status
212 , GetHeaders (Headers h a)
209 , GetHeaders (Headers h a)
213− ) => HasServer (Verb method status ctypes (Headers h a)) where
210+ ) => HasServer (Verb method status ctypes (Headers h a)) config where
215 type ServerT (Verb method status ctypes (Headers h a)) m = m (Headers h a)
212 type ServerT (Verb method status ctypes (Headers h a)) m = m (Headers h a)
216− type HasConfig (Verb method status ctypes (Headers h a)) c = ()
218 route Proxy _ = methodRouterHeaders method (Proxy :: Proxy ctypes) status
214 route Proxy _ = methodRouterHeaders method (Proxy :: Proxy ctypes) status
219 where method = reflectMethod (Proxy :: Proxy method)
215 where method = reflectMethod (Proxy :: Proxy method)
@@ -239,12 +235,11 @@ instance OVERLAPPING_
239-- > server = viewReferer
235-- > server = viewReferer
240-- > where viewReferer :: Referer -> ExceptT ServantErr IO referer
236-- > where viewReferer :: Referer -> ExceptT ServantErr IO referer
241-- > viewReferer referer = return referer
237-- > viewReferer referer = return referer
242−instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout)
238+instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout config)
243− => HasServer (Header sym a :> sublayout) where
239+ => HasServer (Header sym a :> sublayout) config where
245 type ServerT (Header sym a :> sublayout) m =
241 type ServerT (Header sym a :> sublayout) m =
246 Maybe a -> ServerT sublayout m
242 Maybe a -> ServerT sublayout m
247− type HasConfig (Header sym a :> sublayout) c = HasConfig sublayout c
249 route Proxy config subserver = WithRequest $ \ request ->
244 route Proxy config subserver = WithRequest $ \ request ->
250 let mheader = parseHeaderMaybe =<< lookup str (requestHeaders request)
245 let mheader = parseHeaderMaybe =<< lookup str (requestHeaders request)
@@ -272,12 +267,11 @@ instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout)
272-- > where getBooksBy :: Maybe Text -> ExceptT ServantErr IO [Book]
267-- > where getBooksBy :: Maybe Text -> ExceptT ServantErr IO [Book]
273-- > getBooksBy Nothing = ...return all books...
268-- > getBooksBy Nothing = ...return all books...
274-- > getBooksBy (Just author) = ...return books by the given author...
269-- > getBooksBy (Just author) = ...return books by the given author...
275−instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout)
270+instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout config)
276− => HasServer (QueryParam sym a :> sublayout) where
271+ => HasServer (QueryParam sym a :> sublayout) config where
278 type ServerT (QueryParam sym a :> sublayout) m =
273 type ServerT (QueryParam sym a :> sublayout) m =
279 Maybe a -> ServerT sublayout m
274 Maybe a -> ServerT sublayout m
280− type HasConfig (QueryParam sym a :> sublayout) c = HasConfig sublayout c
282 route Proxy config subserver = WithRequest $ \ request ->
276 route Proxy config subserver = WithRequest $ \ request ->
283 let querytext = parseQueryText $ rawQueryString request
277 let querytext = parseQueryText $ rawQueryString request
@@ -309,12 +303,11 @@ instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout)
309-- > server = getBooksBy
303-- > server = getBooksBy
310-- > where getBooksBy :: [Text] -> ExceptT ServantErr IO [Book]
304-- > where getBooksBy :: [Text] -> ExceptT ServantErr IO [Book]
311-- > getBooksBy authors = ...return all books by these authors...
305-- > getBooksBy authors = ...return all books by these authors...
312−instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout)
306+instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout config)
313− => HasServer (QueryParams sym a :> sublayout) where
307+ => HasServer (QueryParams sym a :> sublayout) config where
315 type ServerT (QueryParams sym a :> sublayout) m =
309 type ServerT (QueryParams sym a :> sublayout) m =
316 [a] -> ServerT sublayout m
310 [a] -> ServerT sublayout m
317− type HasConfig (QueryParams sym a :> sublayout) c = HasConfig sublayout c
319 route Proxy config subserver = WithRequest $ \ request ->
312 route Proxy config subserver = WithRequest $ \ request ->
320 let querytext = parseQueryText $ rawQueryString request
313 let querytext = parseQueryText $ rawQueryString request
@@ -341,12 +334,11 @@ instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout)
341-- > server = getBooks
334-- > server = getBooks
342-- > where getBooks :: Bool -> ExceptT ServantErr IO [Book]
335-- > where getBooks :: Bool -> ExceptT ServantErr IO [Book]
343-- > getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...
336-- > getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...
344−instance (KnownSymbol sym, HasServer sublayout)
337+instance (KnownSymbol sym, HasServer sublayout config)
345− => HasServer (QueryFlag sym :> sublayout) where
338+ => HasServer (QueryFlag sym :> sublayout) config where
347 type ServerT (QueryFlag sym :> sublayout) m =
340 type ServerT (QueryFlag sym :> sublayout) m =
348 Bool -> ServerT sublayout m
341 Bool -> ServerT sublayout m
349− type HasConfig (QueryFlag sym :> sublayout) c = HasConfig sublayout c
351 route Proxy config subserver = WithRequest $ \ request ->
343 route Proxy config subserver = WithRequest $ \ request ->
352 let querytext = parseQueryText $ rawQueryString request
344 let querytext = parseQueryText $ rawQueryString request
@@ -367,10 +359,9 @@ instance (KnownSymbol sym, HasServer sublayout)
368-- > server :: Server MyApi
360-- > server :: Server MyApi
369-- > server = serveDirectory "/var/www/images"
361-- > server = serveDirectory "/var/www/images"
370−instance HasServer Raw where
362+instance HasServer Raw config where
372 type ServerT Raw m = Application
364 type ServerT Raw m = Application
373− type HasConfig Raw c = ()
375 route Proxy _ rawApplication = LeafRouter $ \ request respond -> do
366 route Proxy _ rawApplication = LeafRouter $ \ request respond -> do
376 r <- runDelayed rawApplication
367 r <- runDelayed rawApplication
@@ -400,12 +391,11 @@ instance HasServer Raw where
400-- > server = postBook
391-- > server = postBook
401-- > where postBook :: Book -> ExceptT ServantErr IO Book
392-- > where postBook :: Book -> ExceptT ServantErr IO Book
402-- > postBook book = ...insert into your db...
393-- > postBook book = ...insert into your db...
403−instance ( AllCTUnrender list a, HasServer sublayout
394+instance ( AllCTUnrender list a, HasServer sublayout config
404− ) => HasServer (ReqBody list a :> sublayout) where
395+ ) => HasServer (ReqBody list a :> sublayout) config where
406 type ServerT (ReqBody list a :> sublayout) m =
397 type ServerT (ReqBody list a :> sublayout) m =
407 a -> ServerT sublayout m
398 a -> ServerT sublayout m
408− type HasConfig (ReqBody list a :> sublayout) c = HasConfig sublayout c
410 route Proxy config subserver = WithRequest $ \ request ->
400 route Proxy config subserver = WithRequest $ \ request ->
411 route (Proxy :: Proxy sublayout) config (addBodyCheck subserver (bodyCheck request))
401 route (Proxy :: Proxy sublayout) config (addBodyCheck subserver (bodyCheck request))
@@ -426,42 +416,37 @@ instance ( AllCTUnrender list a, HasServer sublayout
427-- | Make sure the incoming request starts with @"/path"@, strip it and
417-- | Make sure the incoming request starts with @"/path"@, strip it and
428-- pass the rest of the request path to @sublayout@.
418-- pass the rest of the request path to @sublayout@.
429−instance (KnownSymbol path, HasServer sublayout) => HasServer (path :> sublayout) where
419+instance (KnownSymbol path, HasServer sublayout config) => HasServer (path :> sublayout) config where
431 type ServerT (path :> sublayout) m = ServerT sublayout m
421 type ServerT (path :> sublayout) m = ServerT sublayout m
432− type HasConfig (path :> sublayout) c = HasConfig sublayout c
434 route Proxy config subserver = StaticRouter $
423 route Proxy config subserver = StaticRouter $
435 M.singleton (cs (symbolVal proxyPath))
424 M.singleton (cs (symbolVal proxyPath))
436 (route (Proxy :: Proxy sublayout) config subserver)
425 (route (Proxy :: Proxy sublayout) config subserver)
437 where proxyPath = Proxy :: Proxy path
426 where proxyPath = Proxy :: Proxy path
439−instance HasServer api => HasServer (RemoteHost :> api) where
428+instance HasServer api config => HasServer (RemoteHost :> api) config where
440 type ServerT (RemoteHost :> api) m = SockAddr -> ServerT api m
429 type ServerT (RemoteHost :> api) m = SockAddr -> ServerT api m
441− type HasConfig (RemoteHost :> api) c = HasConfig api c
443 route Proxy config subserver = WithRequest $ \req ->
431 route Proxy config subserver = WithRequest $ \req ->
444 route (Proxy :: Proxy api) config (passToServer subserver $ remoteHost req)
432 route (Proxy :: Proxy api) config (passToServer subserver $ remoteHost req)
446−instance HasServer api => HasServer (IsSecure :> api) where
434+instance HasServer api config => HasServer (IsSecure :> api) config where
447 type ServerT (IsSecure :> api) m = IsSecure -> ServerT api m
435 type ServerT (IsSecure :> api) m = IsSecure -> ServerT api m
448− type HasConfig (IsSecure :> api) c = HasConfig api c
450 route Proxy config subserver = WithRequest $ \req ->
437 route Proxy config subserver = WithRequest $ \req ->
451 route (Proxy :: Proxy api) config (passToServer subserver $ secure req)
438 route (Proxy :: Proxy api) config (passToServer subserver $ secure req)
453 where secure req = if isSecure req then Secure else NotSecure
440 where secure req = if isSecure req then Secure else NotSecure
455−instance HasServer api => HasServer (Vault :> api) where
442+instance HasServer api config => HasServer (Vault :> api) config where
456 type ServerT (Vault :> api) m = Vault -> ServerT api m
443 type ServerT (Vault :> api) m = Vault -> ServerT api m
457− type HasConfig (Vault :> api) c = HasConfig api c
459 route Proxy config subserver = WithRequest $ \req ->
445 route Proxy config subserver = WithRequest $ \req ->
460 route (Proxy :: Proxy api) config (passToServer subserver $ vault req)
446 route (Proxy :: Proxy api) config (passToServer subserver $ vault req)
462−instance HasServer api => HasServer (HttpVersion :> api) where
448+instance HasServer api config => HasServer (HttpVersion :> api) config where
463 type ServerT (HttpVersion :> api) m = HttpVersion -> ServerT api m
449 type ServerT (HttpVersion :> api) m = HttpVersion -> ServerT api m
464− type HasConfig (HttpVersion :> api) c = HasConfig api c
466 route Proxy config subserver = WithRequest $ \req ->
451 route Proxy config subserver = WithRequest $ \req ->
467 route (Proxy :: Proxy api) config (passToServer subserver $ httpVersion req)
452 route (Proxy :: Proxy api) config (passToServer subserver $ httpVersion req)
@@ -477,11 +462,11 @@ ct_wildcard = "*" <> "/" <> "*" -- Because CPP
478-- * configs
463-- * configs
465+instance (HasConfigEntry config (NamedConfig name subConfig), HasServer subApi subConfig)
480−instance HasServer subApi => HasServer (WithNamedConfig name subConfig subApi) where
466+ => HasServer (WithNamedConfig name subConfig subApi) config where
481 type ServerT (WithNamedConfig name subConfig subApi) m =
468 type ServerT (WithNamedConfig name subConfig subApi) m =
482 ServerT subApi m
469 ServerT subApi m
483− type HasConfig (WithNamedConfig name subConfig subApi) config =
484− (HasConfigEntry config (NamedConfig name subConfig), HasConfig subApi subConfig)
486 route Proxy config delayed =
471 route Proxy config delayed =
487 route subProxy subConfig delayed
472 route subProxy subConfig delayed