|
6 | 6 |
|
7 | 7 | module Servant.Server.Internal.RouteResult where
|
8 | 8 |
|
9 |
| -import Control.Monad (ap, liftM) |
| 9 | +import Control.Monad (ap) |
10 | 10 | import Control.Monad.Base (MonadBase (..))
|
11 |
| -import Control.Monad.Catch (MonadThrow (..)) |
| 11 | +import Control.Monad.Catch (ExitCase (..), MonadCatch (..), MonadMask (..), MonadThrow (..)) |
12 | 12 | import Control.Monad.Trans (MonadIO (..), MonadTrans (..))
|
13 | 13 | import Control.Monad.Trans.Control
|
14 | 14 | ( ComposeSt
|
@@ -72,8 +72,48 @@ instance MonadBaseControl b m => MonadBaseControl b (RouteResultT m) where
|
72 | 72 |
|
73 | 73 | instance MonadTransControl RouteResultT where
|
74 | 74 | type StT RouteResultT a = RouteResult a
|
75 |
| - liftWith f = RouteResultT $ liftM return $ f runRouteResultT |
| 75 | + liftWith f = RouteResultT (return <$> f runRouteResultT) |
76 | 76 | restoreT = RouteResultT
|
77 | 77 |
|
78 | 78 | instance MonadThrow m => MonadThrow (RouteResultT m) where
|
79 | 79 | throwM = lift . throwM
|
| 80 | + |
| 81 | +instance MonadCatch m => MonadCatch (RouteResultT m) where |
| 82 | + catch (RouteResultT m) f = RouteResultT $ catch m (runRouteResultT . f) |
| 83 | + |
| 84 | +instance MonadMask m => MonadMask (RouteResultT m) where |
| 85 | + mask f = RouteResultT $ mask $ \u -> runRouteResultT $ f (q u) |
| 86 | + where |
| 87 | + q |
| 88 | + :: (m (RouteResult a) -> m (RouteResult a)) |
| 89 | + -> RouteResultT m a |
| 90 | + -> RouteResultT m a |
| 91 | + q u (RouteResultT b) = RouteResultT (u b) |
| 92 | + uninterruptibleMask f = RouteResultT $ uninterruptibleMask $ \u -> runRouteResultT $ f (q u) |
| 93 | + where |
| 94 | + q |
| 95 | + :: (m (RouteResult a) -> m (RouteResult a)) |
| 96 | + -> RouteResultT m a |
| 97 | + -> RouteResultT m a |
| 98 | + q u (RouteResultT b) = RouteResultT (u b) |
| 99 | + |
| 100 | + generalBracket acquire release use = RouteResultT $ do |
| 101 | + (eb, ec) <- |
| 102 | + generalBracket |
| 103 | + (runRouteResultT acquire) |
| 104 | + ( \resourceRoute exitCase -> case resourceRoute of |
| 105 | + Fail e -> pure $ Fail e -- nothing to release, acquire didn't succeed |
| 106 | + FailFatal e -> pure $ FailFatal e |
| 107 | + Route resource -> case exitCase of |
| 108 | + ExitCaseSuccess (Route b) -> runRouteResultT (release resource (ExitCaseSuccess b)) |
| 109 | + ExitCaseException e -> runRouteResultT (release resource (ExitCaseException e)) |
| 110 | + _ -> runRouteResultT (release resource ExitCaseAbort) |
| 111 | + ) |
| 112 | + ( \case |
| 113 | + Fail e -> pure $ Fail e -- nothing to release, acquire didn't succeed |
| 114 | + FailFatal e -> pure $ FailFatal e |
| 115 | + Route resource -> runRouteResultT (use resource) |
| 116 | + ) |
| 117 | + -- The order in which we perform those two effects doesn't matter, |
| 118 | + -- since the error message is the same regardless. |
| 119 | + return ((,) <$> eb <*> ec) |
0 commit comments