git.iko.soy/typeable/servant
on master help sign in
Add hoistServer to HasServer
commit24af338dea8b5230888ead8115bf7373baacb0fb authorOleg Grenrus <oleg.grenrus@iki.fi> dateFri 8 Sep 2017, 19:21 (9 years ago) parent50be3a2
7 files changed+77−196
.gitignore+1 servant-server/CHANGELOG.md+9 servant-server/src/Servant/Server/Experimental/Auth.hs+4−3 servant-server/src/Servant/Server/Internal.hs+51−7 servant-server/test/Servant/Server/Internal/RoutingApplicationSpec.hs+3 servant-server/test/Servant/Server/UsingContextSpec/TestCombinators.hs+8 stack-ghc-8.2.1.yaml+1−186
.gitignore+1
@@ -1,5 +1,6 @@
11**/*/dist
22dist-newstyle
3+.ghc.environment.*
34/bin
45/lib
56/share
servant-server/CHANGELOG.md+9
@@ -1,3 +1,12 @@
1+Next
2+----
3+
4+### Breaking changes
5+
6+* Added `hoistServer` member to the `HasServer` class, which is `HasServer`
7+ specific `enter`.
8+ ([#804](https://github.com/haskell-servant/servant/pull/804))
9+
1100.11
211----
312
servant-server/src/Servant/Server/Experimental/Auth.hs+4−3
@@ -21,9 +21,8 @@ import Network.Wai (Request)
2121import Servant ((:>))
2222import Servant.API.Experimental.Auth
2323import Servant.Server.Internal (HasContextEntry,
24− HasServer, ServerT,
25− getContextEntry,
26− route)
24+ HasServer (..),
25+ getContextEntry)
2726import Servant.Server.Internal.RoutingApplication (addAuthCheck,
2827 delayedFailFatal,
2928 DelayedIO,
@@ -58,6 +57,8 @@ instance ( HasServer api context
5857 type ServerT (AuthProtect tag :> api) m =
5958 AuthServerData (AuthProtect tag) -> ServerT api m
6059
60+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
61+
6162 route Proxy context subserver =
6263 route (Proxy :: Proxy api) context (subserver `addAuthCheck` withRequest authCheck)
6364 where
servant-server/src/Servant/Server/Internal.hs+51−7
@@ -8,6 +8,7 @@
88{-# LANGUAGE MultiParamTypeClasses #-}
99{-# LANGUAGE OverloadedStrings #-}
1010{-# LANGUAGE PolyKinds #-}
11+{-# LANGUAGE RankNTypes #-}
1112{-# LANGUAGE ScopedTypeVariables #-}
1213{-# LANGUAGE TypeFamilies #-}
1314{-# LANGUAGE TypeOperators #-}
@@ -33,7 +34,7 @@ import Data.Maybe (fromMaybe, mapMaybe)
3334import Data.Either (partitionEithers)
3435import Data.String (fromString)
3536import Data.String.Conversions (cs, (<>))
36−import Data.Tagged (Tagged(..), untag)
37+import Data.Tagged (Tagged(..), retag, untag)
3738import qualified Data.Text as T
3839import Data.Typeable
3940import GHC.TypeLits (KnownNat, KnownSymbol, natVal,
@@ -85,6 +86,13 @@ class HasServer api context where
8586 -> Delayed env (Server api)
8687 -> Router env
8788
89+ hoistServer
90+ :: Proxy api
91+ -> Proxy context
92+ -> (forall x. m x -> n x)
93+ -> ServerT api m
94+ -> ServerT api n
95+
8896type Server api = ServerT api Handler
8997
9098-- * Instances
@@ -109,6 +117,11 @@ instance (HasServer a context, HasServer b context) => HasServer (a :<|> b) cont
109117 where pa = Proxy :: Proxy a
110118 pb = Proxy :: Proxy b
111119
120+ -- | This is better than 'enter', as it's taylor made for 'HasServer'.
121+ hoistServer _ pc nt (a :<|> b) =
122+ hoistServer (Proxy :: Proxy a) pc nt a :<|>
123+ hoistServer (Proxy :: Proxy b) pc nt b
124+
112125-- | If you use 'Capture' in one of the endpoints for your API,
113126-- this automatically requires your server-side handler to be a function
114127-- that takes an argument of the type specified by the 'Capture'.
@@ -132,6 +145,8 @@ instance (KnownSymbol capture, FromHttpApiData a, HasServer api context)
132145 type ServerT (Capture capture a :> api) m =
133146 a -> ServerT api m
134147
148+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
149+
135150 route Proxy context d =
136151 CaptureRouter $
137152 route (Proxy :: Proxy api)
@@ -158,15 +173,17 @@ instance (KnownSymbol capture, FromHttpApiData a, HasServer api context)
158173-- > server = getSourceFile
159174-- > where getSourceFile :: [Text] -> Handler Book
160175-- > getSourceFile pathSegments = ...
161−instance (KnownSymbol capture, FromHttpApiData a, HasServer sublayout context)
162− => HasServer (CaptureAll capture a :> sublayout) context where
176+instance (KnownSymbol capture, FromHttpApiData a, HasServer api context)
177+ => HasServer (CaptureAll capture a :> api) context where
163178
164− type ServerT (CaptureAll capture a :> sublayout) m =
165− [a] -> ServerT sublayout m
179+ type ServerT (CaptureAll capture a :> api) m =
180+ [a] -> ServerT api m
181+
182+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
166183
167184 route Proxy context d =
168185 CaptureAllRouter $
169− route (Proxy :: Proxy sublayout)
186+ route (Proxy :: Proxy api)
170187 context
171188 (addCapture d $ \ txts -> case parseUrlPieces txts of
172189 Left _ -> delayedFail err400
@@ -241,6 +258,7 @@ instance OVERLAPPABLE_
241258 ) => HasServer (Verb method status ctypes a) context where
242259
243260 type ServerT (Verb method status ctypes a) m = m a
261+ hoistServer _ _ nt s = nt s
244262
245263 route Proxy _ = methodRouter method (Proxy :: Proxy ctypes) status
246264 where method = reflectMethod (Proxy :: Proxy method)
@@ -252,6 +270,7 @@ instance OVERLAPPING_
252270 ) => HasServer (Verb method status ctypes (Headers h a)) context where
253271
254272 type ServerT (Verb method status ctypes (Headers h a)) m = m (Headers h a)
273+ hoistServer _ _ nt s = nt s
255274
256275 route Proxy _ = methodRouterHeaders method (Proxy :: Proxy ctypes) status
257276 where method = reflectMethod (Proxy :: Proxy method)
@@ -283,6 +302,8 @@ instance (KnownSymbol sym, FromHttpApiData a, HasServer api context)
283302 type ServerT (Header sym a :> api) m =
284303 Maybe a -> ServerT api m
285304
305+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
306+
286307 route Proxy context subserver = route (Proxy :: Proxy api) context $
287308 subserver `addHeaderCheck` withRequest headerCheck
288309 where
@@ -326,6 +347,8 @@ instance (KnownSymbol sym, FromHttpApiData a, HasServer api context)
326347 type ServerT (QueryParam sym a :> api) m =
327348 Maybe a -> ServerT api m
328349
350+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
351+
329352 route Proxy context subserver =
330353 let querytext req = parseQueryText $ rawQueryString req
331354 parseParam req =
@@ -371,6 +394,8 @@ instance (KnownSymbol sym, FromHttpApiData a, HasServer api context)
371394 type ServerT (QueryParams sym a :> api) m =
372395 [a] -> ServerT api m
373396
397+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
398+
374399 route Proxy context subserver = route (Proxy :: Proxy api) context $
375400 subserver `addParameterCheck` withRequest paramsCheck
376401 where
@@ -411,6 +436,8 @@ instance (KnownSymbol sym, HasServer api context)
411436 type ServerT (QueryFlag sym :> api) m =
412437 Bool -> ServerT api m
413438
439+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
440+
414441 route Proxy context subserver =
415442 let querytext r = parseQueryText $ rawQueryString r
416443 param r = case lookup paramname (querytext r) of
@@ -434,6 +461,8 @@ instance HasServer Raw context where
434461
435462 type ServerT Raw m = Tagged m Application
436463
464+ hoistServer _ _ _ = retag
465+
437466 route Proxy _ rawApplication = RawRouter $ \ env request respond -> runResourceT $ do
438467 -- note: a Raw application doesn't register any cleanup
439468 -- but for the sake of consistency, we nonetheless run
@@ -473,6 +502,8 @@ instance ( AllCTUnrender list a, HasServer api context
473502 type ServerT (ReqBody list a :> api) m =
474503 a -> ServerT api m
475504
505+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
506+
476507 route Proxy context subserver
477508 = route (Proxy :: Proxy api) context $
478509 addBodyCheck subserver ctCheck bodyCheck
@@ -507,44 +538,51 @@ instance (KnownSymbol path, HasServer api context) => HasServer (path :> api) co
507538 (cs (symbolVal proxyPath))
508539 (route (Proxy :: Proxy api) context subserver)
509540 where proxyPath = Proxy :: Proxy path
541+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt s
510542
511543instance HasServer api context => HasServer (RemoteHost :> api) context where
512544 type ServerT (RemoteHost :> api) m = SockAddr -> ServerT api m
513545
514546 route Proxy context subserver =
515547 route (Proxy :: Proxy api) context (passToServer subserver remoteHost)
548+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
516549
517550instance HasServer api context => HasServer (IsSecure :> api) context where
518551 type ServerT (IsSecure :> api) m = IsSecure -> ServerT api m
519552
520553 route Proxy context subserver =
521554 route (Proxy :: Proxy api) context (passToServer subserver secure)
522−
523555 where secure req = if isSecure req then Secure else NotSecure
524556
557+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
558+
525559instance HasServer api context => HasServer (Vault :> api) context where
526560 type ServerT (Vault :> api) m = Vault -> ServerT api m
527561
528562 route Proxy context subserver =
529563 route (Proxy :: Proxy api) context (passToServer subserver vault)
564+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
530565
531566instance HasServer api context => HasServer (HttpVersion :> api) context where
532567 type ServerT (HttpVersion :> api) m = HttpVersion -> ServerT api m
533568
534569 route Proxy context subserver =
535570 route (Proxy :: Proxy api) context (passToServer subserver httpVersion)
571+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
536572
537573-- | Ignore @'Summary'@ in server handlers.
538574instance HasServer api ctx => HasServer (Summary desc :> api) ctx where
539575 type ServerT (Summary desc :> api) m = ServerT api m
540576
541577 route _ = route (Proxy :: Proxy api)
578+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt s
542579
543580-- | Ignore @'Description'@ in server handlers.
544581instance HasServer api ctx => HasServer (Description desc :> api) ctx where
545582 type ServerT (Description desc :> api) m = ServerT api m
546583
547584 route _ = route (Proxy :: Proxy api)
585+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt s
548586
549587-- | Singleton type representing a server that serves an empty API.
550588data EmptyServer = EmptyServer deriving (Typeable, Eq, Show, Bounded, Enum)
@@ -564,6 +602,8 @@ instance HasServer EmptyAPI context where
564602
565603 route Proxy _ _ = StaticRouter mempty mempty
566604
605+ hoistServer _ _ _ = retag
606+
567607-- | Basic Authentication
568608instance ( KnownSymbol realm
569609 , HasServer api context
@@ -580,6 +620,8 @@ instance ( KnownSymbol realm
580620 basicAuthContext = getContextEntry context
581621 authCheck = withRequest $ \ req -> runBasicAuth req realm basicAuthContext
582622
623+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy api) pc nt . s
624+
583625-- * helpers
584626
585627ct_wildcard :: B.ByteString
@@ -604,3 +646,5 @@ instance (HasContextEntry context (NamedContext name subContext), HasServer subA
604646
605647 subContext :: Context subContext
606648 subContext = descendIntoNamedContext (Proxy :: Proxy name) context
649+
650+ hoistServer _ _ nt s = hoistServer (Proxy :: Proxy subApi) (Proxy :: Proxy subContext) nt s
servant-server/test/Servant/Server/Internal/RoutingApplicationSpec.hs+3
@@ -88,6 +88,9 @@ data Res (sym :: Symbol)
8888
8989instance (KnownSymbol sym, HasServer api ctx) => HasServer (Res sym :> api) ctx where
9090 type ServerT (Res sym :> api) m = IORef (TestResource String) -> ServerT api m
91+
92+ hoistServer _ nc nt s = hoistServer (Proxy :: Proxy api) nc nt . s
93+
9194 route Proxy ctx server = route (Proxy :: Proxy api) ctx $
9295 addBodyCheck server (return ()) check
9396 where
servant-server/test/Servant/Server/UsingContextSpec/TestCombinators.hs+8
@@ -29,6 +29,8 @@ instance (HasContextEntry context String, HasServer subApi context) =>
2929 type ServerT (ExtractFromContext :> subApi) m =
3030 String -> ServerT subApi m
3131
32+ hoistServer _ pc nt s = hoistServer (Proxy :: Proxy subApi) pc nt . s
33+
3234 route Proxy context delayed =
3335 route subProxy context (fmap inject delayed)
3436 where
@@ -45,6 +47,9 @@ instance (HasServer subApi (String ': context)) =>
4547 type ServerT (InjectIntoContext :> subApi) m =
4648 ServerT subApi m
4749
50+ hoistServer _ _ nt s =
51+ hoistServer (Proxy :: Proxy subApi) (Proxy :: Proxy (String ': context)) nt s
52+
4853 route Proxy context delayed =
4954 route subProxy newContext delayed
5055 where
@@ -61,6 +66,9 @@ instance (HasContextEntry context (NamedContext name subContext), HasServer subA
6166 type ServerT (NamedContextWithBirdface name subContext :> subApi) m =
6267 ServerT subApi m
6368
69+ hoistServer _ _ nt s =
70+ hoistServer (Proxy :: Proxy subApi) (Proxy :: Proxy subContext) nt s
71+
6472 route Proxy context delayed =
6573 route subProxy subContext delayed
6674 where
stack-ghc-8.2.1.yaml+1−186
@@ -1,192 +1,7 @@
1−resolver: ghc-8.2.0.20170507
1+resolver: nightly-2017-09-01
22packages:
33- servant-client/
44- servant-docs/
55- servant-foreign/
66- servant-server/
77- servant/
8−extra-deps:
9−- abstract-deque-0.3
10−- abstract-par-0.3.3
11−- adjunctions-4.3
12−- aeson-1.2.0.0
13−- aeson-compat-0.3.7
14−- aeson-pretty-0.8.4
15−- ansi-terminal-0.6.3.1
16−- ansi-wl-pprint-0.6.7.3
17−- appar-0.1.4
18−- asn1-encoding-0.9.5
19−- asn1-parse-0.9.4
20−- asn1-types-0.3.2
21−- async-2.1.1.1
22−- attoparsec-0.13.1.0
23−- attoparsec-iso8601-1.0.0.0
24−- auto-update-0.1.4
25−- base-compat-0.9.3
26−- base-orphans-0.6
27−- base64-bytestring-1.0.0.1
28−- bifunctors-5.4.2
29−- blaze-builder-0.4.0.2
30−- blaze-html-0.9.0.1
31−- blaze-markup-0.8.0.0
32−- byteable-0.1.1
33−- byteorder-1.0.4
34−- bytestring-builder-0.10.8.1.0
35−- cabal-doctest-1.0.2
36−- call-stack-0.1.0
37−- case-insensitive-1.2.0.10
38−- cassava-0.4.5.1
39−- cereal-0.5.4.0
40−- clock-0.7.2
41−- cmdargs-0.10.17
42−- code-page-0.1.3
43−- comonad-5.0.1
44−- connection-0.2.8
45−- contravariant-1.4
46−- control-monad-omega-0.3.1
47−- cookie-0.4.2.1
48−- criterion-1.2.0.0
49−- cryptonite-0.23
50−- data-default-class-0.1.2.0
51−- deepseq-generics-0.2.0.0
52−- distributive-0.5.2
53−- dlist-0.8.0.2
54−- doctest-0.11.2
55−- easy-file-0.2.1
56−- erf-2.0.0.0
57−- exceptions-0.8.3
58−- fail-4.9.0.0
59−- fast-logger-2.4.10
60−- file-embed-0.0.10
61−- filemanip-0.3.6.3
62−- foundation-0.0.9
63−- free-4.12.4
64−- generics-sop-0.3.0.0
65−- ghc-paths-0.1.0.9
66−- Glob-0.8.0
67−- hashable-1.2.6.0
68−- hex-0.1.2
69−- hourglass-0.2.10
70−- hspec-2.4.3
71−- hspec-core-2.4.3
72−- hspec-discover-2.4.3
73−- hspec-expectations-0.8.2
74−- hspec-wai-0.8.0
75−- http-api-data-0.3.7.1
76−- http-client-0.5.7.0
77−- http-client-tls-0.3.5
78−- http-date-0.0.6.1
79−- http-media-0.6.4
80−- http-types-0.9.1
81−- http2-1.6.3
82−- HUnit-1.6.0.0
83−- integer-logarithms-1.0.1
84−- iproute-1.7.1
85−- js-flot-0.8.3
86−- js-jquery-3.2.1
87−- kan-extensions-5.0.2
88−- lens-4.15.2
89−- lifted-base-0.2.3.11
90−- math-functions-0.2.1.0
91−- memory-0.14.5
92−- microstache-1
93−- mime-types-0.1.0.7
94−- mmorph-1.1.0
95−- monad-control-1.0.1.0
96−- monad-par-0.3.4.8
97−- monad-par-extras-0.3.3
98−- mtl-2.2.1
99−- mwc-random-0.13.6.0
100−- nats-1.1.1
101−- natural-transformation-0.4
102−- network-2.6.3.2
103−- network-uri-2.6.1.0
104−- old-locale-1.0.0.7
105−- old-time-1.1.0.3
106−- optparse-applicative-0.13.2.0
107−- parallel-3.2.1.1
108−- parsec-3.1.11
109−- pem-0.2.2
110−- prelude-extras-0.4.0.3
111−- primitive-0.6.2.0
112−- profunctors-5.2
113−- psqueues-0.2.2.3
114−- QuickCheck-2.9.2
115−- quickcheck-instances-0.3.13
116−- quickcheck-io-0.1.4
117−- random-1.1
118−- reflection-2.1.2
119−- regex-base-0.93.2
120−- regex-tdfa-1.2.2
121−- resourcet-1.1.9
122−- safe-0.3.14
123−- scientific-0.3.4.13
124−- semigroupoids-5.2
125−- semigroups-0.18.3
126−- setenv-0.1.1.3
127−- should-not-typecheck-2.1.0
128−- simple-sendfile-0.2.25
129−- socks-0.5.5
130−- split-0.2.3.2
131−- StateVar-1.1.0.4
132−- statistics-0.14.0.2
133−- stm-2.4.4.1
134−- streaming-commons-0.1.18
135−- string-conversions-0.4.0.1
136−- stringsearch-0.3.6.6
137−- syb-0.7
138−- system-filepath-0.4.13.4
139−- tagged-0.8.5
140−- tasty-0.11.2.1
141−- tasty-hunit-0.9.2
142−- tasty-quickcheck-0.8.4
143−- temporary-1.2.0.4
144−- text-1.2.2.2
145−- tf-random-0.5
146−- th-lift-0.7.7
147−- th-lift-instances-0.1.11
148−- time-locale-compat-0.1.1.3
149−- tls-1.3.10
150−- transformers-base-0.4.4
151−- transformers-compat-0.5.1.4
152−- unbounded-delays-0.1.1.0
153−- unix-compat-0.4.3.1
154−- unix-time-0.3.7
155−- unordered-containers-0.2.8.0
156−- uri-bytestring-0.2.3.3
157−- url-2.1.3
158−- utf8-string-1.0.1.1
159−- uuid-types-1.0.3
160−- vault-0.3.0.7
161−- vector-0.12.0.1
162−- vector-algorithms-0.7.0.1
163−- vector-binary-instances-0.2.3.5
164−- vector-th-unbox-0.2.1.6
165−- void-0.7.2
166−- wai-3.2.1.1
167−- wai-app-static-3.1.6.1
168−- wai-extra-3.0.19.1
169−- wai-logger-2.3.0
170−- warp-3.2.12
171−- word8-0.1.2
172−- x509-1.6.5
173−- x509-store-1.6.2
174−- x509-system-1.6.4
175−- x509-validation-1.6.5
176−- zlib-0.6.1.2
177−flags:
178− time-locale-compat:
179− old-locale: false
180−compiler: ghc-8.2.0.20170507
181−compiler-check: match-exact
182−setup-info:
183− ghc:
184− linux64:
185− 8.2.0.20170507:
186− url: https://downloads.haskell.org/~ghc/8.2.1-rc2/ghc-8.2.0.20170507-x86_64-deb8-linux.tar.xz
187− macosx:
188− 8.2.0.20170507:
189− url: https://downloads.haskell.org/~ghc/8.2.1-rc2/ghc-8.2.0.20170507-x86_64-apple-darwin.tar.xz
190− windows64:
191− 8.2.0.20170507:
192− url: https://downloads.haskell.org/~ghc/8.2.1-rc2/ghc-8.2.0.20170507-x86_64-unknown-mingw32.tar.xz