-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A functional web framework.
--   
--   A Haskell web framework where you write plain old functions.
--   
--   <i>Provided you have</i> <a>stack</a> <i>installed, you can run this
--   example like a shell script (it'll listen on port 3000):</i>
--   
--   <pre>
--   #!/usr/bin/env stack
--   -- stack --resolver lts-5.5 --install-ghc runghc --package fn --package warp
--   {-# LANGUAGE OverloadedStrings #-}
--   import Data.Monoid ((&lt;&gt;))
--   import Data.Text (Text)
--   import Network.Wai (Response)
--   import Network.Wai.Handler.Warp (run)
--   import Web.Fn
--   
--   data Ctxt = Ctxt { _req :: FnRequest }
--   instance RequestContext Ctxt where
--     getRequest = _req
--     setRequest c r = c { _req = r }
--   
--   initializer :: IO Ctxt
--   initializer = return (Ctxt defaultFnRequest)
--   
--   main :: IO ()
--   main = do ctxt &lt;- initializer
--             run 3000 $ toWAI ctxt site
--   
--   site :: Ctxt -&gt; IO Response
--   site ctxt = route ctxt [ end                        ==&gt; indexH
--                          , path "echo" // param "msg" ==&gt; echoH
--                          , path "echo" // segment     ==&gt; echoH
--                          ]
--                     `fallthrough` notFoundText "Page not found."
--   
--   indexH :: Ctxt -&gt; IO (Maybe Response)
--   indexH _ = okText "Try visiting /echo?msg=<a>hello</a> or /echo/hello"
--   
--   echoH :: Ctxt -&gt; Text -&gt; IO (Maybe Response)
--   echoH _ msg = okText $ "Echoing '" &lt;&gt; msg &lt;&gt; "'."
--   </pre>
--   
--   Fn lets you write web code that just looks like normal Haskell code.
--   
--   <ul>
--   <li>An application has some "context", which must contain a
--   <tt>Request</tt>, but can contain other data as well, like database
--   connection pools, etc. This context will be passed to each of your
--   handlers, updated with the current HTTP Request.</li>
--   <li>Routes are declared to capture parameters and/or segments of the
--   url, and then routed to handler functions that have the appropriate
--   number and type of arguments. These functions return <tt>IO (Maybe
--   Response)</tt>, where <tt>Nothing</tt> indicates to Fn that you want
--   it to keep looking for matching routes.</li>
--   <li>All handlers just use plain old <tt>IO</tt>, which means it is
--   easy to call them from GHCi, <tt>forkIO</tt>, etc.</li>
--   <li>All of this is a small wrapper around the WAI interface, so you
--   have the flexilibility to do anything you need to do with HTTP.</li>
--   </ul>
--   
--   The name comes from the fact that Fn emphasizes functions (over
--   monads), where all necessary data is passed via function arguments,
--   and control flow is mediated by return values.
@package fn
@version 0.3.0.2


-- | This package provides a simple framework for routing and responses.
--   The two primary goals are:
--   
--   <ol>
--   <li>All web handler functions are just plain IO. There is no Fn monad,
--   or monad transformer. This has a lot of nice properties, foremost
--   among them is that it is easier to call handlers from other contexts
--   (like GHCi, when testing, in other threads, etc). As a result, these
--   functions take a single extra parameter that has the context that they
--   need (like database connection pools, the request, etc).</li>
--   <li>Web handlers are functions with typed parameters. When routing, we
--   specify many parameters (most commonly, numeric ids, but can be many
--   things), so the handlers should be functions that take those as
--   parameters.</li>
--   </ol>
module Web.Fn

-- | A normal WAI <a>Request</a> and the parsed post body (if present). We
--   can only parse the body once, so we need to have our request (which we
--   pass around) to be able to have the parsed body.
type FnRequest = (Request, PostMVar)

-- | A default request, which is a WAI defaultRequest and a place for an
--   MVar where post info will be placed (if you parse the post body).
--   
--   Warning: If you try to parse the post body (with <a>!=&gt;</a>)
--   without replacing the Nothing placeholder with an actual MVar, it will
--   blow up!
defaultFnRequest :: FnRequest

-- | Specify the way that Fn can get the <a>FnRequest</a> out of your
--   context.
--   
--   The easiest way to instantiate this is to use the lens, but if you
--   don't want to use lenses, define <a>getRequest</a> and
--   <a>setRequest</a>.
--   
--   Note that <a>requestLens</a> is defined in terms of <a>getRequest</a>
--   and <a>setRequest</a> and vice-versa, so you need to define _one_ of
--   these.
class RequestContext ctxt
requestLens :: (RequestContext ctxt, Functor f) => (FnRequest -> f FnRequest) -> ctxt -> f ctxt
getRequest :: RequestContext ctxt => ctxt -> FnRequest
setRequest :: RequestContext ctxt => ctxt -> FnRequest -> ctxt

-- | Convert an Fn application (provide a context, a context to response
--   function and we'll create a WAI application by updating the
--   <a>FnRequest</a> value for each call).
toWAI :: RequestContext ctxt => ctxt -> (ctxt -> IO Response) -> Application

-- | The parts of the path, when split on /, and the query.
type Req = (Request, [Text], Query, StdMethod, PostMVar)

-- | The type of a route, constructed with 'pattern ==&gt; handler'.
type Route ctxt = ctxt -> Req -> IO (Maybe (IO (Maybe Response)))

-- | The main construct for Fn, <a>route</a> takes a context (which it will
--   pass to all handlers) and a list of potential matches (which, once
--   they match, may still end up deciding not to handle the request -
--   hence the double <a>Maybe</a>). It can be nested.
--   
--   <pre>
--   app c = route c [ end ==&gt; index
--                   , path "foo" // path "bar" // segment /? param "id ==&gt; h]
--     where index :: Ctxt -&gt; IO (Maybe Response)
--           index _ = okText "This is the index."
--           h :: Ctxt -&gt; Text -&gt; Text -&gt; IO (Maybe Response)
--           h _ s i = okText ("got path /foo/" &lt;&gt; s &lt;&gt; ", with id=" &lt;&gt; i)
--   </pre>
route :: RequestContext ctxt => ctxt -> [Route ctxt] -> IO (Maybe Response)

-- | The <a>route</a> function (and all your handlers) return 'IO (Maybe
--   Response)', because each can elect to not respond (in which case we
--   will continue to match on routes). But to construct an application, we
--   need a response in the case that nothing matched - this is what
--   <a>fallthrough</a> allows you to specify. In particular,
--   <a>notFoundText</a> and <a>notFoundHtml</a> may be useful.
fallthrough :: IO (Maybe Response) -> IO Response -> IO Response

-- | The non-body parsing connective between route patterns and the handler
--   that will be called if the pattern matches. The type is not
--   particularly illuminating, as it uses polymorphism to be able to match
--   route patterns with varying numbers (and types) of parts with
--   functions of the corresponding number of arguments and types.
(==>) :: RequestContext ctxt => (Req -> IO (Maybe (Req, k -> a))) -> (ctxt -> k) -> ctxt -> Req -> IO (Maybe a)

-- | The connective between route patterns and the handler that parses the
--   body, which allows post params to be extracted with <a>param</a> and
--   allows <a>file</a> to work (otherwise, it will trigger a runtime
--   error).
(!=>) :: RequestContext ctxt => (Req -> IO (Maybe (Req, k -> a))) -> (ctxt -> k) -> ctxt -> Req -> IO (Maybe a)

-- | Connects two path segments. Note that when normally used, the type
--   parameter r is <a>Req</a>. It is more general here to facilitate
--   testing.
(//) :: (r -> IO (Maybe (r, k -> k'))) -> (r -> IO (Maybe (r, k' -> a))) -> r -> IO (Maybe (r, k -> a))

-- | A synonym for <a>//</a>. To be removed

-- | <i>Deprecated: Use the identical <a>//</a> instead.</i>
(/?) :: (r -> IO (Maybe (r, k -> k'))) -> (r -> IO (Maybe (r, k' -> a))) -> r -> IO (Maybe (r, k -> a))

-- | Matches a literal part of the path. If there is no path part left, or
--   the next part does not match, the whole match fails.
path :: Text -> Req -> IO (Maybe (Req, a -> a))

-- | Matches there being no parts of the path left. This is useful when
--   matching index routes.
end :: Req -> IO (Maybe (Req, a -> a))

-- | Matches anything.
anything :: Req -> IO (Maybe (Req, a -> a))

-- | Captures a part of the path. It will parse the part into the type
--   specified by the handler it is matched to. If there is no segment, or
--   if the segment cannot be parsed as such, it won't match.
segment :: FromParam p => Req -> IO (Maybe (Req, (p -> a) -> a))

-- | Matches on a particular HTTP method.
method :: StdMethod -> Req -> IO (Maybe (Req, a -> a))

-- | A class that is used for parsing for <a>param</a> and <a>paramOpt</a>.
--   and <a>segment</a>.
class FromParam a
fromParam :: FromParam a => [Text] -> Either ParamError a
data ParamError
ParamMissing :: ParamError
ParamTooMany :: ParamError
ParamUnparsable :: ParamError
ParamOtherError :: Text -> ParamError

-- | Matches on a query parameter of the given name. It is parsed into the
--   type needed by the handler, which can be a <a>Maybe</a> type if the
--   parameter is optional, or a list type if there can be many. If the
--   parameters cannot be parsed into the type needed by the handler, it
--   won't match.
--   
--   Note: If you have used the <a>!=&gt;</a> connective, so that the
--   request body has been parsed, this will also match post parameters
--   (and will combine the two together). If you haven't used that
--   connective (so the pattern is matched to handler with <a>==&gt;</a>),
--   it will only match query parameters.
param :: FromParam p => Text -> Req -> IO (Maybe (Req, (p -> a) -> a))

-- | Matches on query parameters of the given name. If there are no
--   parameters, or they cannot be parsed into the type needed by the
--   handler, it won't match.

-- | <i>Deprecated: Use <a>param</a> with a list type, or define param
--   parsing for non-empty list.</i>
paramMany :: FromParam p => Text -> Req -> IO (Maybe (Req, ([p] -> a) -> a))

-- | If the specified parameters are present, they will be parsed into the
--   type needed by the handler, but if they aren't present or cannot be
--   parsed, the handler will still be called.
--   
--   Note: If you have used the <a>!=&gt;</a> connective, so that the
--   request body has been parsed, this will also match post parameters
--   (and will combine the two together). If you haven't used that
--   connective (so the pattern is matched to handler with <a>==&gt;</a>),
--   it will only match query parameters.
paramOpt :: FromParam p => Text -> Req -> IO (Maybe (Req, (Either ParamError p -> a) -> a))

-- | An uploaded file.
data File
File :: Text -> Text -> FilePath -> File
[fileName] :: File -> Text
[fileContentType] :: File -> Text
[filePath] :: File -> FilePath

-- | Matches an uploaded file with the given parameter name.
file :: Text -> Req -> IO (Maybe (Req, (File -> a) -> a))

-- | Matches all uploaded files, passing their parameter names and
--   contents.
files :: Req -> IO (Maybe (Req, ([(Text, File)] -> a) -> a))

-- | Serves static files out of the specified path according to the request
--   path. Note that if you have matched parts of the path, those will not
--   be included in the path used to find the static file. For example, if
--   you have a file <tt>static/img/a.png</tt>, and do:
--   
--   <pre>
--   path "img" ==&gt; staticServe "static"
--   </pre>
--   
--   It will match <tt>img/img/a.png</tt>, not <tt>img/a.png</tt>. If you
--   wanted that, you could:
--   
--   <pre>
--   anything ==&gt; staticServe "static"
--   </pre>
--   
--   If no file is found, or if the path has <tt>..</tt> or starts with
--   <tt>/</tt>, this will continue routing.
staticServe :: RequestContext ctxt => Text -> ctxt -> IO (Maybe Response)

-- | Sends a specific file specified by path. It will specify the
--   content-type if it can figure it out by the file extension.
--   
--   If no file exists at the given path, it will keep routing.
sendFile :: FilePath -> IO (Maybe Response)

-- | Returns <a>Text</a> as a response.
okText :: Text -> IO (Maybe Response)

-- | Returns <a>Text</a> as a JSON response with appropriate header.
okJson :: Text -> IO (Maybe Response)

-- | Returns Html (in <a>Text</a>) as a response.
okHtml :: Text -> IO (Maybe Response)

-- | Returns <a>Text</a> as a response with a 500 status code.
errText :: Text -> IO (Maybe Response)

-- | Returns Html (in <a>Text</a>) as a response with a 500 status code.
errHtml :: Text -> IO (Maybe Response)

-- | Returns a 404 with the given <a>Text</a> as a body. Note that this
--   returns a 'IO Response' not an 'IO (Maybe Response)' because the
--   expectaiton is that you are calling this with <a>fallthrough</a>.
notFoundText :: Text -> IO Response

-- | Returns a 404 with the given html as a body. Note that this returns a
--   'IO Response' not an 'IO (Maybe Response)' because the expectaiton is
--   that you are calling this with <a>fallthrough</a>.
notFoundHtml :: Text -> IO Response

-- | Redirects to the given url. Note that the target is not validated, so
--   it should be an absolute path/url.
redirect :: Text -> IO (Maybe Response)

-- | Redirects to the referrer, if present in headers, else to "/".
redirectReferer :: RequestContext ctxt => ctxt -> IO (Maybe Response)

-- | Internal helper - uses the name of the file as the pattern.
tempFileBackEnd' :: InternalState -> ignored1 -> FileInfo () -> IO ByteString -> IO FilePath
instance GHC.Show.Show Web.Fn.ParamError
instance GHC.Classes.Eq Web.Fn.ParamError
instance Web.Fn.FromParam Data.Text.Internal.Text
instance Web.Fn.FromParam GHC.Types.Int
instance Web.Fn.FromParam GHC.Types.Double
instance Web.Fn.FromParam a => Web.Fn.FromParam [a]
instance Web.Fn.FromParam a => Web.Fn.FromParam (GHC.Base.Maybe a)
instance Web.Fn.RequestContext Web.Fn.FnRequest
instance GHC.Base.Functor (Web.Fn.Store b)
