    {-# LANGUAGE Safe #-}
    {- |
    Frank is a Sinatra-inspired DSL (see <http://www.sinatrarb.com>) for creating
    routes. It is composable with all 'ToApplication' types, but is designed to be used
    with 'Network.Wai.Controller's. Each verb ('get', 'post', 'put', etc') takes a
    URL pattern of the form \"\/dir\/:paramname\/dir\" (see 'routePattern' for
    details) and a 'ToApplication':

    @
      main :: IO ()
      main = run 3000 $ controllerApp () $ do
        get \"\/\" $ do
          req <- request
          respond $ okHtml $ fromString $
            \"Welcome Home \" ++ (show $ serverName req)
        get \"\/user\/:id\" $ do
          userId \<- queryParam \"id\" >>= fromMaybe \"\"
          respond $ ok \"text/json\" $ fromString $
            \"{\\\"myid\\\": \" ++ (show userId) ++ \"}\"
        put \"\/user\/:id\" $ do
          ...
    @

    -}
    module Web.Frank
      ( get
      , post
      , put
      , patch
      , delete
      , options
      ) where

    import Network.HTTP.Types
    import Web.Simple.Controller.Trans
    import Data.Text (Text)

    -- | Helper method
    frankMethod :: Monad m
                => StdMethod -> Text -> ControllerT s m a
                -> ControllerT s m ()
    frankMethod :: StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    frankMethod method :: StdMethod
    method pattern :: Text
    pattern = StdMethod -> ControllerT s m () -> ControllerT s m ()
    forall (m :: * -> *) s a.
    Monad m =>
    StdMethod -> ControllerT s m a -> ControllerT s m ()
    routeMethod StdMethod
    method (ControllerT s m () -> ControllerT s m ())
    -> (ControllerT s m a -> ControllerT s m ())
    -> ControllerT s m a
    -> ControllerT s m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> ControllerT s m () -> ControllerT s m ()
    forall (m :: * -> *) s a.
    Monad m =>
    Text -> ControllerT s m a -> ControllerT s m ()
    routePattern Text
    pattern (ControllerT s m () -> ControllerT s m ())
    -> (ControllerT s m a -> ControllerT s m ())
    -> ControllerT s m a
    -> ControllerT s m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ControllerT s m a -> ControllerT s m ()
    forall (m :: * -> *) s a.
    Monad m =>
    ControllerT s m a -> ControllerT s m ()
    routeTop

    -- | Matches the GET method on the given URL pattern
    get :: Monad m => Text -> ControllerT s m a -> ControllerT s m ()
    get :: Text -> ControllerT s m a -> ControllerT s m ()
    get = StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    forall (m :: * -> *) s a.
    Monad m =>
    StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    frankMethod StdMethod
    GET

    -- | Matches the POST method on the given URL pattern
    post :: Monad m => Text -> ControllerT s m a -> ControllerT s m ()
    post :: Text -> ControllerT s m a -> ControllerT s m ()
    post = StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    forall (m :: * -> *) s a.
    Monad m =>
    StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    frankMethod StdMethod
    POST

    -- | Matches the PUT method on the given URL pattern
    put :: Monad m => Text -> ControllerT s m a -> ControllerT s m ()
    put :: Text -> ControllerT s m a -> ControllerT s m ()
    put = StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    forall (m :: * -> *) s a.
    Monad m =>
    StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    frankMethod StdMethod
    PUT

    -- | Matches the PATCH method on the given URL pattern
    patch :: Monad m => Text -> ControllerT s m a -> ControllerT s m ()
    patch :: Text -> ControllerT s m a -> ControllerT s m ()
    patch = StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    forall (m :: * -> *) s a.
    Monad m =>
    StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    frankMethod StdMethod
    PATCH

    -- | Matches the DELETE method on the given URL pattern
    delete :: Monad m => Text -> ControllerT s m a -> ControllerT s m ()
    delete :: Text -> ControllerT s m a -> ControllerT s m ()
    delete = StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    forall (m :: * -> *) s a.
    Monad m =>
    StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    frankMethod StdMethod
    DELETE

    -- | Matches the OPTIONS method on the given URL pattern
    options :: Monad m => Text -> ControllerT s m a -> ControllerT s m ()
    options :: Text -> ControllerT s m a -> ControllerT s m ()
    options = StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    forall (m :: * -> *) s a.
    Monad m =>
    StdMethod -> Text -> ControllerT s m a -> ControllerT s m ()
    frankMethod StdMethod
    OPTIONS