servant-router 0.8.1 → 0.9.0
raw patch · 4 files changed
+30/−32 lines, 4 filesdep −mtlPVP ok
version bump matches the API change (PVP)
Dependencies removed: mtl
API changes (from Hackage documentation)
- Servant.Router: routeLoc :: MonadError RoutingError m => Location -> Router m a -> m a
+ Servant.Router: routeLoc :: Monad m => Location -> Router m a -> m (Either RoutingError a)
- Servant.Router: runRoute :: forall layout m a. (HasRouter layout, MonadError RoutingError m) => String -> Proxy layout -> RouteT layout m a -> m a
+ Servant.Router: runRoute :: forall layout m a. (HasRouter layout, Monad m) => String -> Proxy layout -> RouteT layout m a -> m (Either RoutingError a)
- Servant.Router: runRouteLoc :: forall layout m a. (HasRouter layout, MonadError RoutingError m) => Location -> Proxy layout -> RouteT layout m a -> m a
+ Servant.Router: runRouteLoc :: forall layout m a. (HasRouter layout, Monad m) => Location -> Proxy layout -> RouteT layout m a -> m (Either RoutingError a)
Files
- README.md +1/−1
- servant-router.cabal +1/−4
- src/Servant/Router.hs +21/−19
- test/Spec.hs +7/−8
README.md view
@@ -46,7 +46,7 @@ -- Here you would display the search bar plus results. return never -- With the handler constructed, run the router with the uri.- result <- runExceptT $ runRoute uri myApi handler+ result <- runRoute uri myApi handler case result of -- If 'Left', there was no correct route for the uri. Left _ -> do
servant-router.cabal view
@@ -1,5 +1,5 @@ name: servant-router-version: 0.8.1+version: 0.9.0 synopsis: Servant router for non-server applications. description: Write Servant APIs to be routed without a server. homepage: https://github.com/ElvishJerricco/servant-router@@ -23,7 +23,6 @@ , http-types == 0.9.* , network-uri == 2.6.* , bytestring == 0.10.*- , mtl == 2.2.* default-language: Haskell2010 ghc-options: -Wall @@ -34,7 +33,6 @@ build-depends: base , servant-router , servant- , mtl ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010 @@ -46,7 +44,6 @@ , servant-router , servant-server , servant-blaze- , mtl , warp , blaze-html ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
src/Servant/Router.hs view
@@ -9,7 +9,6 @@ module Servant.Router where -import Control.Monad.Except import qualified Data.ByteString.Char8 as BS import Data.Proxy import Data.Text (Text)@@ -133,8 +132,8 @@ -- | Use a handler to route a 'Location'. -- Normally 'runRoute' should be used instead, unless you want custom -- handling of string failing to parse as 'URI'.-runRouteLoc :: forall layout m a. (HasRouter layout, MonadError RoutingError m)- => Location -> Proxy layout -> RouteT layout m a -> m a+runRouteLoc :: forall layout m a. (HasRouter layout, Monad m)+ => Location -> Proxy layout -> RouteT layout m a -> m (Either RoutingError a) runRouteLoc loc layout page = let routing = route layout (Proxy :: Proxy m) (Proxy :: Proxy a) page in routeLoc loc routing@@ -142,44 +141,47 @@ -- | Use a handler to route a location, represented as a 'String'. -- All handlers must, in the end, return @m a@. -- 'routeLoc' will choose a route and return its result.-runRoute :: forall layout m a. (HasRouter layout, MonadError RoutingError m)- => String -> Proxy layout -> RouteT layout m a -> m a+runRoute :: forall layout m a. (HasRouter layout, Monad m)+ => String -> Proxy layout -> RouteT layout m a -> m (Either RoutingError a) runRoute uriString layout page = case uriToLocation <$> parseURIReference uriString of- Nothing -> throwError FailFatal+ Nothing -> return $ Left FailFatal Just loc -> runRouteLoc loc layout page -- | Use a computed 'Router' to route a 'Location'.-routeLoc :: MonadError RoutingError m => Location -> Router m a -> m a+routeLoc :: Monad m => Location -> Router m a -> m (Either RoutingError a) routeLoc loc r = case r of- RChoice a b -> catchError (routeLoc loc a) $ \e -> case e of- Fail -> routeLoc loc b- FailFatal -> throwError e+ RChoice a b -> do+ result <- routeLoc loc a+ case result of+ Left Fail -> routeLoc loc b+ Left FailFatal -> return $ Left FailFatal+ Right x -> return $ Right x RCapture f -> case locPath loc of- [] -> throwError Fail+ [] -> return $ Left Fail capture:paths -> maybe- (throwError FailFatal)+ (return $ Left FailFatal) (routeLoc loc { locPath = paths }) (f <$> parseUrlPieceMaybe capture) RQueryParam sym f -> case lookup (BS.pack $ symbolVal sym) (locQuery loc) of Nothing -> routeLoc loc $ f Nothing- Just Nothing -> throwError FailFatal+ Just Nothing -> return $ Left FailFatal Just (Just text) -> case parseQueryParamMaybe (decodeUtf8 text) of- Nothing -> throwError FailFatal+ Nothing -> return $ Left FailFatal Just x -> routeLoc loc $ f (Just x)- RQueryParams sym f -> maybe (throwError FailFatal) (routeLoc loc . f) $ do+ RQueryParams sym f -> maybe (return $ Left FailFatal) (routeLoc loc . f) $ do ps <- sequence $ snd <$> filter (\(k, _) -> k == BS.pack (symbolVal sym)) (locQuery loc) sequence $ (parseQueryParamMaybe . decodeUtf8) <$> ps RQueryFlag sym f -> case lookup (BS.pack $ symbolVal sym) (locQuery loc) of Nothing -> routeLoc loc $ f False Just Nothing -> routeLoc loc $ f True- Just (Just _) -> throwError FailFatal+ Just (Just _) -> return $ Left FailFatal RPath sym a -> case locPath loc of- [] -> throwError Fail+ [] -> return $ Left Fail p:paths -> if p == T.pack (symbolVal sym) then routeLoc (loc { locPath = paths }) a- else throwError Fail- RPage a -> a+ else return $ Left Fail+ RPage a -> Right <$> a -- | Convert a 'URI' to a 'Location'. uriToLocation :: URI -> Location
test/Spec.hs view
@@ -1,9 +1,8 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} -import Control.Monad.Except+import Data.Foldable import Data.Proxy-import Data.Traversable import Servant.API import Servant.Router @@ -24,10 +23,10 @@ main :: IO () main = do- let root :: Int -> Maybe String -> ExceptT RoutingError IO ()- root i s = liftIO $ print (i, s)- other :: String -> ExceptT RoutingError IO ()- other s = liftIO $ print s- void $ for testUris $ \uri -> do- result <- runExceptT $ runRoute uri testApi (root :<|> other)+ let root :: Int -> Maybe String -> IO ()+ root i s = print (i, s)+ other :: String -> IO ()+ other = print+ for_ testUris $ \uri -> do+ result <- runRoute uri testApi (root :<|> other) print result