packages feed

web-inv-route 0.1.2.3 → 0.1.3.0

raw patch · 18 files changed

+57/−22 lines, 18 files

Files

Web/Route/Invertible/Map/Bool.hs view
@@ -7,8 +7,6 @@   , lookupBool   ) where -import Data.Semigroup (Semigroup((<>)))- -- |A trivial, flat representation of a 'Bool'-keyed map. -- Value existance (but not the values themselves) is strict. data BoolMap v = BoolMap
Web/Route/Invertible/Map/Const.hs view
@@ -12,8 +12,6 @@   , flattenConstDefaultMap   ) where -import Data.Semigroup (Semigroup((<>)))- import Web.Route.Invertible.Map.Default  -- |A monoid map where every key (additionally) maps to the same constant value, parameterized over the type of the map.
Web/Route/Invertible/Map/Custom.hs view
@@ -6,7 +6,6 @@   ) where  import Data.Maybe (mapMaybe)-import Data.Semigroup (Semigroup) import Text.Show.Functions ()  newtype CustomMap q a b = CustomMap [(q -> Maybe a, b)]
Web/Route/Invertible/Map/Default.hs view
@@ -10,7 +10,6 @@   ) where  import Control.Applicative ((<|>))-import Data.Semigroup (Semigroup((<>)))  -- |A map that also provides a default value, for when a key is not found in the underlying map, parameterized over the type of the map. data DefaultMap m v = DefaultMap
Web/Route/Invertible/Map/Monoid.hs view
@@ -12,7 +12,6 @@  import Data.Foldable (fold) import qualified Data.Map.Strict as M-import Data.Semigroup (Semigroup((<>)))  -- |A specialized version of 'M.Map'. newtype MonoidMap k a = MonoidMap { monoidMap :: M.Map k a }
Web/Route/Invertible/Map/MonoidHash.hs view
@@ -13,7 +13,6 @@ import Data.Foldable (fold) import Data.Hashable (Hashable) import qualified Data.HashMap.Strict as M-import Data.Semigroup (Semigroup((<>)))  -- |A specialized version of 'M.HashMap'. newtype MonoidHashMap k a = MonoidHashMap { monoidHashMap :: M.HashMap k a }
Web/Route/Invertible/Map/Placeholder.hs view
@@ -18,7 +18,6 @@ import Data.Dynamic (Dynamic) import qualified Data.HashMap.Strict as HM import qualified Data.Map.Strict as M-import Data.Semigroup (Semigroup((<>)))  import Web.Route.Invertible.String import Web.Route.Invertible.Placeholder
Web/Route/Invertible/Map/Query.hs view
@@ -8,7 +8,6 @@   ) where  import qualified Data.HashMap.Lazy as HM-import Data.Semigroup (Semigroup((<>)))  import Web.Route.Invertible.Placeholder import Web.Route.Invertible.Map.Placeholder
Web/Route/Invertible/Map/Route.hs view
@@ -20,7 +20,6 @@ import Data.Dynamic (Dynamic, toDyn) import qualified Data.HashMap.Strict as HM import qualified Data.Map.Strict as Map-import Data.Semigroup (Semigroup((<>)))  import Web.Route.Invertible.String import Web.Route.Invertible.Sequence
Web/Route/Invertible/Map/Sequence.hs view
@@ -33,7 +33,6 @@ import Control.Invertible.Monoidal.Free import Control.Monad (MonadPlus(..)) import Control.Monad.Trans.State (evalState)-import Data.Semigroup (Semigroup((<>)))  import Web.Route.Invertible.String import Web.Route.Invertible.Placeholder
Web/Route/Invertible/Monoid/Exactly.hs view
@@ -11,7 +11,6 @@  import Control.Applicative (Alternative(..)) import Control.Monad (MonadPlus(..))-import Data.Semigroup (Semigroup((<>)))  -- |A 'Maybe'-like monoid that only allows one value, overflowing into 'Conflict' when more than one 'Exactly' are combined (with '<|>' or 'Data.Monoid.<>', which thus function identically). data Exactly a
Web/Route/Invertible/Monoid/Prioritized.hs view
@@ -4,8 +4,6 @@   ( Prioritized(..)   ) where -import Data.Semigroup (Semigroup((<>)))- -- |A trival monoid allowing each item to be given a priority when combining. data Prioritized a = Prioritized   { priority :: !Int -- ^ The priority this value, where larger numeric values have higher priority and take precedence over lower priorities.
Web/Route/Invertible/Path.hs view
@@ -19,7 +19,6 @@  import Control.Invertible.Monoidal import qualified Data.ByteString.Builder as B-import Data.Monoid ((<>)) import qualified Data.Invertible as I import Data.String (IsString(..)) import qualified Data.Text as T
+ Web/Route/Invertible/Render.hs view
@@ -0,0 +1,43 @@+-- |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
Web/Route/Invertible/Result.hs view
@@ -5,7 +5,6 @@   ) where  import qualified Data.ByteString.Char8 as BSC-import Data.Semigroup (Semigroup((<>))) import Data.Typeable (Typeable) import Network.HTTP.Types.Header (ResponseHeaders, hAllow) import Network.HTTP.Types.Status (Status, notFound404, methodNotAllowed405, internalServerError500)
Web/Route/Invertible/Sequence.hs view
@@ -27,7 +27,6 @@ import           Control.Invertible.Monoidal import           Control.Invertible.Monoidal.Free import           Control.Monad (MonadPlus, mzero, guard)-import           Control.Monad.Fail (MonadFail) import qualified Data.Invertible as I import           Data.String (IsString(..)) 
test/Main.hs view
@@ -1,13 +1,16 @@ {-# LANGUAGE OverloadedStrings #-} module Main (main) where -import Data.Maybe (fromJust)-import Network.URI (parseURI)-import System.Exit (exitSuccess, exitFailure)+import qualified Data.ByteString.Lazy as BS+import qualified Data.ByteString.Builder as BSB+import           Data.Maybe (fromJust)+import           Network.URI (parseURI)+import           System.Exit (exitSuccess, exitFailure) import qualified Test.HUnit as U  import Web.Route.Invertible import Web.Route.Invertible.URI+import Web.Route.Invertible.Render  getThing :: RouteAction Int String getThing = routeMethod GET *< routePath ("thing" *< parameter) `RouteAction` \i ->@@ -62,17 +65,23 @@ req :: RouteAction r a -> r -> (Method, String) req a = fmap show . routeActionURI a +ren :: RouteAction r a -> r -> BS.ByteString+ren r a = BSB.toLazyByteString $ renderUrlRequestBuilder (requestActionRoute r a) []+ tests :: U.Test tests = U.test   [ rte GET "http:/thing/0"           U.~?= RouteResult "get thing0"   , rte GET "http:/thing/-3?type=x"   U.~?= RouteResult "get thing-3:x"   , req getThingQ (98, '=')           U.~?= (GET, "http:/thing/98?type=%3D")+  , ren getThingQ (98, '=')           U.~?= "http:/thing/98?type=%3D"   , rte PUT "http:/thing/09"          U.~?= RouteResult "put thing9"   , req postThing "foo"               U.~?= (POST, "http:/thing/foo")+  , ren postThing "foo"               U.~?= "http:/thing/foo"   , rte OPTIONS "http:/thing/xxx"     U.~?= AllowedMethods [POST]   , rte PUT "http:/thing/0/sub/12/34" U.~?= RouteResult "thing0 sub 12 34"   , rte GET "http:/things/0/12/34"    U.~?= RouteResult "ignore thing0"   , req ignoredThing (-3)             U.~?= (GET, "http:/things/-3/ign")+  , ren ignoredThing (-3)             U.~?= "http:/things/-3/ign"   , rte POST "http://foo.com/foo"     U.~?= AllowedMethods [GET]   , rte POST "http:/foo"              U.~?= RouteNotFound   ]
web-inv-route.cabal view
@@ -1,5 +1,5 @@ name:                web-inv-route-version:             0.1.2.3+version:             0.1.3.0 synopsis:            Composable, reversible, efficient web routing using invertible invariants and bijections description:   Utilities to route HTTP requests, mainly focused on path components.  Routes are specified using bijections and invariant functors, allowing run-time composition (routes can be distributed across modules), reverse and forward routing derived from the same specification, and O(log n) lookups.@@ -46,6 +46,7 @@     Web.Route.Invertible     Web.Route.Invertible.Common     Web.Route.Invertible.Internal+    Web.Route.Invertible.Render   other-modules:     Web.Route.Invertible.String     Web.Route.Invertible.Parameter