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


-- | Use boomerang for type-safe URL parsers/printers
--   
--   This module add support for creating url parsers/printers using a
--   single unified grammar specification
@package web-routes-boomerang
@version 0.28.4.2


-- | <tt>web-routes-boomerang</tt> makes it easy to use write custom
--   pretty-printers and parsers for your URL types. Instead of writing a
--   parser and a separate pretty-printer you can specify both at once by
--   using the <tt>boomerang</tt> library:
--   
--   <a>http://hackage.haskell.org/package/boomerang</a>
--   
--   This demo will show the basics of getting started.
--   
--   First we need to enable some language extensions:
--   
--   <pre>
--   {-# LANGUAGE TemplateHaskell, TypeOperators, OverloadedStrings #-}
--   </pre>
--   
--   <pre>
--   module Main where
--   </pre>
--   
--   Note in the imports that we hide <tt>(id, (.))</tt> from the
--   <a>Prelude</a> and use the versions from <a>Control.Category</a>
--   instead.
--   
--   <pre>
--   import Prelude              hiding (id, (.))
--   import Control.Category     (Category(id, (.)))
--   import Control.Monad.Trans  (MonadIO(liftIO))
--   import Text.Boomerang.TH    (makeBoomerangs)
--   import Web.Routes           (Site(..), RouteT(..), decodePathInfo, encodePathInfo, runSite, showURL)
--   import Web.Routes.Boomerang (Router, (&lt;&gt;), (&lt;/&gt;), int, parse1, boomerangSiteRouteT, anyString, parseStrings)
--   </pre>
--   
--   Next we define a data type that represents our sitemap.
--   
--   <pre>
--   -- | the routes
--   data Sitemap
--      = Home
--      | UserOverview
--      | UserDetail Int
--      | Article Int String
--      deriving (Eq, Show)
--   </pre>
--   
--   To use the <tt>Sitemap</tt> type with <tt>boomerang</tt> we need to
--   call <tt>makeBoomerangs</tt>:
--   
--   <pre>
--   $(makeBoomerangs ''Sitemap)
--   </pre>
--   
--   That will create new combinators corresponding to the constructors for
--   <tt>Sitemap</tt>. They will be named, <tt>rHome</tt>,
--   <tt>rUserOverview</tt>, etc.
--   
--   Now we can specify how the <tt>Sitemap</tt> type is mapped to a url
--   and back:
--   
--   <pre>
--   sitemap :: Router Sitemap
--   sitemap =
--       (  rHome
--       &lt;&gt; "users" . users
--       &lt;&gt; rArticle . ("article" &lt;/&gt; int . "-" . anyString)
--       )
--     where
--       users  =  rUserOverview
--              &lt;&gt; rUserDetail &lt;/&gt; int
--   </pre>
--   
--   The mapping looks like this:
--   
--   <pre>
--   /                       &lt;=&gt; Home
--   /users                  &lt;=&gt; UserOverview
--   /users/<i><a>int</a></i>            &lt;=&gt; UserDetail <i><a>int</a></i>
--   /article/<i><a>int</a></i>-<i><a>string</a></i> &lt;=&gt; Article <i><a>int</a></i> <i><a>string</a></i>
--   </pre>
--   
--   Next we have our function which maps a parsed route to the handler for
--   that route. (There is nothing <tt>boomerang</tt> specific about this
--   function):
--   
--   <pre>
--   handle :: Sitemap -&gt; RouteT Sitemap IO ()
--   handle url =
--       case url of
--         _ -&gt; do liftIO $ print url
--                 s &lt;- showURL url
--                 liftIO $ putStrLn s
--   </pre>
--   
--   Normally the <tt>case</tt> statement would match on the different
--   constructors and map them to different handlers. But in this case we
--   use the same handler for all constructors. Also, instead of running in
--   the IO monad, we would typically use a web framework monad like
--   Happstack's <tt>ServerPartT</tt>.
--   
--   The handler does two things:
--   
--   <ol>
--   <li>prints the parsed url</li>
--   <li>unparses the url and prints it</li>
--   </ol>
--   
--   We now have two pieces:
--   
--   <ol>
--   <li><tt>sitemap</tt> - which converts urls to the <tt>Sitemap</tt>
--   type and back</li>
--   <li><tt>handle</tt> - which maps <tt>Sitemap</tt> to handlers</li>
--   </ol>
--   
--   We tie these two pieces together use <a>boomerangSiteRouteT</a>:
--   
--   <pre>
--   site :: Site Sitemap (IO ())
--   site = boomerangSiteRouteT handle sitemap
--   </pre>
--   
--   This gives as a standard <a>Site</a> value that we can use with
--   <tt>runSite</tt> or with framework specific wrappers like
--   <tt>implSite</tt>.
--   
--   If we were not using <a>RouteT</a> then we could use
--   <tt>boomerangSite</tt> instead.
--   
--   Now we can create a simple test function that takes the path info part
--   of a url and runs our site:
--   
--   <pre>
--   test :: ByteString -- ^ path info of incoming url
--        -&gt; IO ()
--   test path =
--       case runSite "" site (decodePathInfo path) of
--         (Left e)   -&gt; putStrLn e
--         (Right io) -&gt; io
--   </pre>
--   
--   We can use it like this:
--   
--   <pre>
--   ghci&gt; test "users/1"
--   UserDetail 1
--   users/1
--   </pre>
--   
--   Here is a simple wrapper to call test interactively:
--   
--   <pre>
--   -- | interactively call 'test'
--   main :: IO ()
--   main = mapM_ test =&lt;&lt; fmap lines getContents
--   </pre>
--   
--   Here are two more helper functions you can use to experiment
--   interactively:
--   
--   <pre>
--   -- | a little function to test rendering a url
--   showurl :: Sitemap -&gt; String
--   showurl url =
--       let (ps, params) = formatPathSegments site url
--       in (encodePathInfo ps params)
--   </pre>
--   
--   <pre>
--   -- | a little function to test parsing a url
--   testParse :: String -&gt; Either String Sitemap
--   testParse pathInfo =
--       case parsePathSegments site $ decodePathInfo pathInfo of
--         (Left e)  -&gt; Left (show e)
--         (Right a) -&gt; Right a
--   </pre>
module Web.Routes.Boomerang

-- | 'Router a b' is a simple type alias for 'Boomerang TextsError [Text] a
--   b'
type Router a b = Boomerang TextsError [Text] a b

-- | function which creates a <a>Site</a> from a <a>Router</a> and a
--   handler
boomerangSite :: ((url -> [(Text, Maybe Text)] -> Text) -> url -> a) -> Router () (url :- ()) -> Site url a

-- | function which creates a <a>Site</a> from a <a>Router</a> and a
--   <a>RouteT</a> handler
boomerangSiteRouteT :: (url -> RouteT url m a) -> Router () (url :- ()) -> Site url (m a)

-- | convert to a <a>URLParser</a> so we can create a <a>PathInfo</a>
--   instance
boomerangFromPathSegments :: Boomerang TextsError [Text] () (url :- ()) -> URLParser url

-- | convert to the type expected by <a>toPathSegments</a> from
--   <a>PathInfo</a>
boomerangToPathSegments :: Boomerang TextsError [Text] () (url :- ()) -> url -> [Text]
