packages feed

salvia-0.1: src/Network/Salvia/Handler/Fallback.hs

module Network.Salvia.Handler.Fallback (hOr, hEither) where

import Control.Applicative
import Control.Monad.State
import Data.Record.Label
import Network.Protocol.Http
import Network.Salvia.Httpd

{- |
Until I figure out how to do this correctly, this handler somewow implements
the MonadPlus/Alternative instance using a custom function.

When the first handler fails the response will be reset and the second handler
is executed. Failure is indicated by an HTTP response `Status` bigger than or
equal to 400 (`BadRequest`). See `statusFailure`.
-}

hOr :: Handler a -> Handler a -> Handler a
hOr h0 h1 = do
  a  <- h0
  st <- getM (status % response)
  if statusFailure st
    then reset >> h1
    else return a

{- |
Like the `hOr` function, but the types of the alternatives may differ because
the values are packed up in an `Either`.
-}

hEither :: Handler a -> Handler b -> Handler (Either a b)
hEither h0 h1 = (Left <$> h0) `hOr` (Right <$> h1)