module Web.Simple.Controller.Exception where

import qualified Control.Exception as E
import           Control.Monad.Trans.Control
import           Web.Simple.Controller

onException :: Controller s a -> Controller s b -> Controller s a
onException :: Controller s a -> Controller s b -> Controller s a
onException act :: Controller s a
act handler :: Controller s b
handler = (RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
-> Controller s a
forall (b :: * -> *) (m :: * -> *) a.
MonadBaseControl b m =>
(RunInBase m b -> b (StM m a)) -> m a
control ((RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
 -> Controller s a)
-> (RunInBase (ControllerT s IO) IO
    -> IO (StM (ControllerT s IO) a))
-> Controller s a
forall a b. (a -> b) -> a -> b
$ \runInM :: RunInBase (ControllerT s IO) IO
runInM -> do
  Controller s a -> IO (StM (ControllerT s IO) a)
RunInBase (ControllerT s IO) IO
runInM Controller s a
act IO (Either Response a, s)
-> IO (Either Response b, s) -> IO (Either Response a, s)
forall a b. IO a -> IO b -> IO a
`E.onException` Controller s b -> IO (StM (ControllerT s IO) b)
RunInBase (ControllerT s IO) IO
runInM Controller s b
handler

finally :: Controller s a -> Controller s b -> Controller s a
finally :: Controller s a -> Controller s b -> Controller s a
finally act :: Controller s a
act next :: Controller s b
next = (RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
-> Controller s a
forall (b :: * -> *) (m :: * -> *) a.
MonadBaseControl b m =>
(RunInBase m b -> b (StM m a)) -> m a
control ((RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
 -> Controller s a)
-> (RunInBase (ControllerT s IO) IO
    -> IO (StM (ControllerT s IO) a))
-> Controller s a
forall a b. (a -> b) -> a -> b
$ \runInM :: RunInBase (ControllerT s IO) IO
runInM -> ((forall a. IO a -> IO a) -> IO (Either Response a, s))
-> IO (StM (ControllerT s IO) a)
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
E.mask (((forall a. IO a -> IO a) -> IO (Either Response a, s))
 -> IO (StM (ControllerT s IO) a))
-> ((forall a. IO a -> IO a) -> IO (Either Response a, s))
-> IO (StM (ControllerT s IO) a)
forall a b. (a -> b) -> a -> b
$ \restore :: forall a. IO a -> IO a
restore -> do
  (Either Response a, s)
r <- IO (Either Response a, s) -> IO (Either Response a, s)
forall a. IO a -> IO a
restore (Controller s a -> IO (StM (ControllerT s IO) a)
RunInBase (ControllerT s IO) IO
runInM Controller s a
act) IO (Either Response a, s)
-> IO (Either Response b, s) -> IO (Either Response a, s)
forall a b. IO a -> IO b -> IO a
`E.onException` (Controller s b -> IO (StM (ControllerT s IO) b)
RunInBase (ControllerT s IO) IO
runInM Controller s b
next)
  (Either Response b, s)
_ <- Controller s b -> IO (StM (ControllerT s IO) b)
RunInBase (ControllerT s IO) IO
runInM Controller s b
next
  (Either Response a, s) -> IO (Either Response a, s)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Response a, s)
r

bracket :: Controller s a -> (a -> Controller s b)
        -> (a -> Controller s c) -> Controller s c
bracket :: Controller s a
-> (a -> Controller s b) -> (a -> Controller s c) -> Controller s c
bracket aquire :: Controller s a
aquire release :: a -> Controller s b
release act :: a -> Controller s c
act = (RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) c))
-> Controller s c
forall (b :: * -> *) (m :: * -> *) a.
MonadBaseControl b m =>
(RunInBase m b -> b (StM m a)) -> m a
control ((RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) c))
 -> Controller s c)
-> (RunInBase (ControllerT s IO) IO
    -> IO (StM (ControllerT s IO) c))
-> Controller s c
forall a b. (a -> b) -> a -> b
$ \runInM :: RunInBase (ControllerT s IO) IO
runInM -> ((forall a. IO a -> IO a) -> IO (Either Response c, s))
-> IO (StM (ControllerT s IO) c)
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
E.mask (((forall a. IO a -> IO a) -> IO (Either Response c, s))
 -> IO (StM (ControllerT s IO) c))
-> ((forall a. IO a -> IO a) -> IO (Either Response c, s))
-> IO (StM (ControllerT s IO) c)
forall a b. (a -> b) -> a -> b
$ \restore :: forall a. IO a -> IO a
restore -> do
  let release' :: (Either Response a, s) -> IO (StM (ControllerT s IO) b)
release' a :: (Either Response a, s)
a = Controller s b -> IO (StM (ControllerT s IO) b)
RunInBase (ControllerT s IO) IO
runInM (Controller s b -> IO (StM (ControllerT s IO) b))
-> Controller s b -> IO (StM (ControllerT s IO) b)
forall a b. (a -> b) -> a -> b
$ StM (ControllerT s IO) a -> Controller s a
forall (b :: * -> *) (m :: * -> *) a.
MonadBaseControl b m =>
StM m a -> m a
restoreM (Either Response a, s)
StM (ControllerT s IO) a
a Controller s a -> (a -> Controller s b) -> Controller s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> Controller s b
release
  (Either Response a, s)
a <- Controller s a -> IO (StM (ControllerT s IO) a)
RunInBase (ControllerT s IO) IO
runInM Controller s a
aquire
  (Either Response c, s)
r <- (IO (Either Response c, s) -> IO (Either Response c, s)
forall a. IO a -> IO a
restore (IO (Either Response c, s) -> IO (Either Response c, s))
-> IO (Either Response c, s) -> IO (Either Response c, s)
forall a b. (a -> b) -> a -> b
$ Controller s c -> IO (Either Response c, s)
RunInBase (ControllerT s IO) IO
runInM (Controller s c -> IO (Either Response c, s))
-> Controller s c -> IO (Either Response c, s)
forall a b. (a -> b) -> a -> b
$ StM (ControllerT s IO) a -> Controller s a
forall (b :: * -> *) (m :: * -> *) a.
MonadBaseControl b m =>
StM m a -> m a
restoreM (Either Response a, s)
StM (ControllerT s IO) a
a Controller s a -> (a -> Controller s c) -> Controller s c
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> Controller s c
act) IO (Either Response c, s)
-> IO (Either Response b, s) -> IO (Either Response c, s)
forall a b. IO a -> IO b -> IO a
`E.onException` (Either Response a, s) -> IO (StM (ControllerT s IO) b)
release' (Either Response a, s)
a
  (Either Response b, s)
_ <- (Either Response a, s) -> IO (StM (ControllerT s IO) b)
release' (Either Response a, s)
a
  (Either Response c, s) -> IO (Either Response c, s)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Response c, s)
r

handle :: E.Exception e => (e -> Controller s a) -> Controller s a
       -> Controller s a
handle :: (e -> Controller s a) -> Controller s a -> Controller s a
handle handler :: e -> Controller s a
handler act :: Controller s a
act = (RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
-> Controller s a
forall (b :: * -> *) (m :: * -> *) a.
MonadBaseControl b m =>
(RunInBase m b -> b (StM m a)) -> m a
control ((RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
 -> Controller s a)
-> (RunInBase (ControllerT s IO) IO
    -> IO (StM (ControllerT s IO) a))
-> Controller s a
forall a b. (a -> b) -> a -> b
$ \runInM :: RunInBase (ControllerT s IO) IO
runInM -> do
  (e -> IO (Either Response a, s))
-> IO (Either Response a, s) -> IO (Either Response a, s)
forall e a. Exception e => (e -> IO a) -> IO a -> IO a
E.handle (Controller s a -> IO (Either Response a, s)
RunInBase (ControllerT s IO) IO
runInM (Controller s a -> IO (Either Response a, s))
-> (e -> Controller s a) -> e -> IO (Either Response a, s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> Controller s a
handler) (IO (Either Response a, s) -> IO (StM (ControllerT s IO) a))
-> IO (Either Response a, s) -> IO (StM (ControllerT s IO) a)
forall a b. (a -> b) -> a -> b
$ Controller s a -> IO (StM (ControllerT s IO) a)
RunInBase (ControllerT s IO) IO
runInM Controller s a
act