1+ {-# LANGUAGE AllowAmbiguousTypes #-}
2+ -- Allow redendudant constraints to require IOE for runWarp helpers.
3+ {-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
4+
5+ module Effectful.Servant.Generic
6+ ( -- * main api
7+ runWarpServerSettings
8+ , runWarpServerSettingsContext
9+ , runWarpServerSettingsSocket
10+ , runWarpServerSettingsSocketContext
11+
12+ -- * helpers
13+ , serveEff
14+
15+ -- * types
16+ , GenericServantConstraints
17+ )
18+ where
19+
20+ import Data.Kind (Type )
21+ import Effectful
22+ import Effectful.Dispatch.Static
23+ import Effectful.Dispatch.Static.Primitive (Env )
24+ import Effectful.Error.Static
25+ import Effectful.Servant (interpretServer )
26+ import qualified Network.Socket as Network
27+ import qualified Network.Wai as Wai
28+ import qualified Network.Wai.Handler.Warp as Warp
29+ import Servant hiding ((:>) )
30+ import Servant.Server.Generic
31+
32+ -- | Deploy an effectful server.
33+ runWarpServerSettings
34+ :: forall routes (es :: [Effect ])
35+ . (GenericServantConstraints routes '[] (Eff (Error ServerError : es )))
36+ => Warp. Settings
37+ -> routes (AsServerT (Eff (Error ServerError : es )))
38+ -> Wai. Middleware
39+ -> Eff es ()
40+ runWarpServerSettings settings = runWarpServerSettingsContext settings EmptyContext
41+ {-# INLINEABLE runWarpServerSettings #-}
42+
43+ -- | Deploy an effectful server with a context.
44+ runWarpServerSettingsContext
45+ :: forall routes (context :: [Type ]) (es :: [Effect ])
46+ . (GenericServantConstraints routes context (Eff (Error ServerError : es )))
47+ => Warp. Settings
48+ -> Context context
49+ -> routes (AsServerT (Eff (Error ServerError : es )))
50+ -> Wai. Middleware
51+ -> Eff es ()
52+ runWarpServerSettingsContext settings ctx routes middleware = do
53+ unsafeEff $ \ es -> do
54+ Warp. runSettings settings (middleware $ serveEff es routes ctx)
55+ {-# INLINEABLE runWarpServerSettingsContext #-}
56+
57+ -- | Deploy an effectful server on socket.
58+ runWarpServerSettingsSocket
59+ :: forall routes (es :: [Effect ])
60+ . (GenericServantConstraints routes '[] (Eff (Error ServerError : es )))
61+ => Warp. Settings
62+ -> Network. Socket
63+ -> routes (AsServerT (Eff (Error ServerError : es )))
64+ -> Wai. Middleware
65+ -> Eff es ()
66+ runWarpServerSettingsSocket settings socket routes =
67+ runWarpServerSettingsSocketContext settings socket routes EmptyContext
68+ {-# INLINEABLE runWarpServerSettingsSocket #-}
69+
70+ -- | Deploy an effectful server on socket with a context.
71+ runWarpServerSettingsSocketContext
72+ :: forall routes (context :: [Type ]) (es :: [Effect ])
73+ . (GenericServantConstraints routes context (Eff (Error ServerError : es )))
74+ => Warp. Settings
75+ -> Network. Socket
76+ -> routes (AsServerT (Eff (Error ServerError : es )))
77+ -> Context context
78+ -> Wai. Middleware
79+ -> Eff es ()
80+ runWarpServerSettingsSocketContext settings socket routes ctx middleware = do
81+ unsafeEff $ \ es -> do
82+ Warp. runSettingsSocket settings socket (middleware $ serveEff es routes ctx)
83+ {-# INLINEABLE runWarpServerSettingsSocketContext #-}
84+
85+ -- | Convert an effectful server into a wai application.
86+ serveEff
87+ :: forall routes (context :: [Type ]) (es :: [Effect ])
88+ . (GenericServantConstraints routes context (Eff (Error ServerError : es )))
89+ => Env es
90+ -> routes (AsServerT (Eff (Error ServerError : es )))
91+ -> Context context
92+ -- -> ServerT api ()
93+ -> Application
94+ serveEff env = genericServeTWithContext (interpretServer env)
95+ {-# INLINEABLE serveEff #-}
96+
97+ type GenericServantConstraints routes ctx m =
98+ ( GenericServant routes (AsServerT m )
99+ , GenericServant routes AsApi
100+ , HasServer (ToServantApi routes ) ctx
101+ , HasContextEntry (ctx .++ DefaultErrorFormatters ) ErrorFormatters
102+ , ServerT (ToServantApi routes ) m ~ ToServant routes (AsServerT m )
103+ )
0 commit comments