-- 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. -- -- Provided you have stack installed, you can run this -- example like a shell script (it'll listen on port 3000): -- --
-- #!/usr/bin/env stack
-- -- stack --resolver lts-5.5 --install-ghc runghc --package fn --package warp
-- {-# LANGUAGE OverloadedStrings #-}
-- import Data.Monoid ((<>))
-- 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 <- initializer
-- run 3000 $ toWAI ctxt site
--
-- site :: Ctxt -> IO Response
-- site ctxt = route ctxt [ end ==> indexH
-- , path "echo" // param "msg" ==> echoH
-- , path "echo" // segment ==> echoH
-- ]
-- `fallthrough` notFoundText "Page not found."
--
-- indexH :: Ctxt -> IO (Maybe Response)
-- indexH _ = okText "Try visiting /echo?msg=hello or /echo/hello"
--
-- echoH :: Ctxt -> Text -> IO (Maybe Response)
-- echoH _ msg = okText $ "Echoing '" <> msg <> "'."
--
--
-- Fn lets you write web code that just looks like normal Haskell code.
--
--
-- app c = route c [ end ==> index
-- , path "foo" // path "bar" // segment /? param "id ==> h]
-- where index :: Ctxt -> IO (Maybe Response)
-- index _ = okText "This is the index."
-- h :: Ctxt -> Text -> Text -> IO (Maybe Response)
-- h _ s i = okText ("got path /foo/" <> s <> ", with id=" <> i)
--
route :: RequestContext ctxt => ctxt -> [Route ctxt] -> IO (Maybe Response)
-- | The route 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
-- fallthrough allows you to specify. In particular,
-- notFoundText and notFoundHtml 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 param and
-- allows file 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 Req. 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 //. To be removed
-- | Deprecated: Use the identical // instead.
(/?) :: (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 param and paramOpt.
-- and segment.
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 Maybe 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 !=> 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 ==>),
-- 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.
-- | Deprecated: Use param with a list type, or define param
-- parsing for non-empty list.
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 !=> 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 ==>),
-- 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 static/img/a.png, and do:
--
-- -- path "img" ==> staticServe "static" ---- -- It will match img/img/a.png, not img/a.png. If you -- wanted that, you could: -- --
-- anything ==> staticServe "static" ---- -- If no file is found, or if the path has .. or starts with -- /, 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 Text as a response. okText :: Text -> IO (Maybe Response) -- | Returns Text as a JSON response with appropriate header. okJson :: Text -> IO (Maybe Response) -- | Returns Html (in Text) as a response. okHtml :: Text -> IO (Maybe Response) -- | Returns Text as a response with a 500 status code. errText :: Text -> IO (Maybe Response) -- | Returns Html (in Text) as a response with a 500 status code. errHtml :: Text -> IO (Maybe Response) -- | Returns a 404 with the given Text 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 fallthrough. 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 fallthrough. 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 GHC.Base.Functor (Web.Fn.Store b) instance Web.Fn.RequestContext Web.Fn.FnRequest 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)