web-inv-route-0.1.3.0: Web/Route/Invertible/Render.hs
-- |Render requests in various ways
module Web.Route.Invertible.Render
( renderRequestBuilder
, renderUrlRequestBuilder
, renderHamletUrl
) where
import Control.Arrow (second)
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Builder as B
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import Network.HTTP.Types.URI (Query, encodePathSegments, renderQueryBuilder, simpleQueryToQuery, queryTextToQuery)
import Web.Route.Invertible.Request
import Web.Route.Invertible.Query
import Web.Route.Invertible.Route
-- |This renders a request along with additional query parameters as @[//host][/path][?query]@.
-- Each component is included only if it's specified by the route.
renderRequestBuilder :: Request -> Query -> B.Builder
renderRequestBuilder r q =
bh (requestHost r)
<> bp (requestPath r)
<> renderQueryBuilder True ((simpleQueryToQuery $ paramsQuerySimple $ requestQuery r) ++ q)
where
bh [] = mempty
bh [x] = sl <> sl <> B.byteString x
bh (x:l) = bh l <> B.char8 '.' <> B.byteString x
bp [] = sl
bp p = encodePathSegments p
sl = B.char8 '/'
-- |This renders a request along with additional query parameters as @scheme:[//host][/path][?query]@.
-- It's roughly equivalent to rendering the 'Web.Route.Invertible.URI.requestURI'.
renderUrlRequestBuilder :: Request -> Query -> B.Builder
renderUrlRequestBuilder r q =
B.string8 (if requestSecure r then "https:" else "http:") <> renderRequestBuilder r q
-- |A 'Text.Hamlet.Render' function, suitable for passing to a @'Text.Hamlet.HtmlUrl' (RouteAction a b, a)@ template.
renderHamletUrl :: (RouteAction a b, a) -> [(T.Text, T.Text)] -> T.Text
renderHamletUrl (r, a) q = TE.decodeUtf8 $ BSL.toStrict $ B.toLazyByteString
$ renderRequestBuilder (requestActionRoute r a) $ queryTextToQuery $ map (second Just) q