{-# LANGUAGE
OverloadedStrings
, DeriveDataTypeable
#-}
module Main where
import Network.Wai.Handler.Warp
import Network.Wai.Middleware.Verbs
import Network.Wai.Middleware.ContentType (textOnly)
import Network.Wai.Trans
import qualified Data.Text.Lazy as LT
import Data.Monoid
import Data.Typeable
import Control.Monad.IO.Class
import Control.Monad.Catch
theEmbeddedApp :: ( MonadIO m
) => LT.Text -> ApplicationT m
theEmbeddedApp v _ respond =
respond $ textOnly $ v <> " Verb accepted!"
data UploadError = UploadFailed
deriving (Show, Typeable)
instance Exception UploadError
myListener :: ( MonadIO m
, MonadThrow m
) => VerbListenerT (ApplicationT m) m ()
myListener = do
get $ theEmbeddedApp "GET"
put uploadFail $ theEmbeddedApp "PUT" -- should never work
post uploadSucceed $ theEmbeddedApp "POST"
delete $ theEmbeddedApp "DELETE"
where
uploadFail _ = throwM UploadFailed
uploadSucceed _ = return ()
handleError :: ( MonadIO m
) => UploadError -> ApplicationT m
handleError UploadFailed _ respond =
respond $ textOnly "Upload Failed!"
myApp :: ( MonadIO m
, MonadCatch m
) => MiddlewareT m
myApp app req respond =
findResponse `catch` (\e -> handleError e req respond)
where
findResponse = do
let v = getVerb req
xs <- execVerbListenerT myListener
mr <- lookupVerb req v xs
case mr of
Nothing -> app req respond
Just r -> r req respond
main :: IO ()
main = run 3000 (myApp defApp)
where
defApp :: Application
defApp _ respond =
respond $ textOnly "404"