servant-server 0.4.0 → 0.4.1
raw patch · 6 files changed
+54/−25 lines, 6 filesdep +filepathdep ~attoparsecdep ~eitherdep ~wai-app-static
Dependencies added: filepath
Dependency ranges changed: attoparsec, either, wai-app-static
Files
- CHANGELOG.md +6/−0
- example/greet.hs +1/−1
- servant-server.cabal +8/−6
- src/Servant/Server/Internal.hs +14/−14
- src/Servant/Utils/StaticFiles.hs +11/−3
- test/Doctests.hs +14/−1
CHANGELOG.md view
@@ -1,3 +1,9 @@+0.4.1+-----+* Bump attoparsec upper bound to < 0.14+* Bump wai-app-static upper bound to < 3.2+* Bump either upper bound to < 4.5+ 0.4 --- * `Delete` now is like `Get`, `Post`, `Put`, and `Patch` and returns a response body
example/greet.hs view
@@ -44,7 +44,7 @@ -- There's one handler per endpoint, which, just like in the type -- that represents the API, are glued together using :<|>. ----- Each handler runs in the 'EitherT (Int, String) IO' monad.+-- Each handler runs in the 'EitherT ServantErr IO' monad. server :: Server TestApi server = helloH :<|> postGreetH :<|> deleteGreetH
servant-server.cabal view
@@ -1,11 +1,10 @@ name: servant-server-version: 0.4.0+version: 0.4.1 synopsis: A family of combinators for defining webservices APIs and serving them description: A family of combinators for defining webservices APIs and serving them .- You can learn about the basics in <http://haskell-servant.github.io/getting-started/ the getting started>- guide.+ You can learn about the basics in the <http://haskell-servant.github.io/tutorial tutorial>. . <https://github.com/haskell-servant/servant/blob/master/servant-server/example/greet.hs Here> is a runnable example, with comments, that defines a dummy API and implements@@ -42,9 +41,9 @@ build-depends: base >= 4.7 && < 5 , aeson >= 0.7 && < 0.9- , attoparsec >= 0.12 && < 0.13+ , attoparsec >= 0.12 && < 0.14 , bytestring >= 0.10 && < 0.11- , either >= 4.3 && < 4.4+ , either >= 4.3 && < 4.5 , http-types >= 0.8 && < 0.9 , network-uri >= 2.6 && < 2.7 , mtl >= 2 && < 3@@ -54,10 +53,11 @@ , split >= 0.2 && < 0.3 , string-conversions >= 0.3 && < 0.4 , system-filepath >= 0.4 && < 0.5+ , filepath >= 1 , text >= 1.2 && < 1.3 , transformers >= 0.3 && < 0.5 , wai >= 3.0 && < 3.1- , wai-app-static >= 3.0 && < 3.1+ , wai-app-static >= 3.0 && < 3.2 , warp >= 3.0 && < 3.1 hs-source-dirs: src default-language: Haskell2010@@ -114,6 +114,8 @@ , servant , doctest , filemanip+ , directory+ , filepath type: exitcode-stdio-1.0 main-is: test/Doctests.hs buildable: True
src/Servant/Server/Internal.hs view
@@ -227,7 +227,7 @@ -- > -- > server :: Server MyApi -- > server = getBook--- > where getBook :: Text -> EitherT (Int, String) IO Book+-- > where getBook :: Text -> EitherT ServantErr IO Book -- > getBook isbn = ... instance (KnownSymbol capture, FromText a, HasServer sublayout) => HasServer (Capture capture a :> sublayout) where@@ -253,7 +253,7 @@ -- -- The code of the handler will, just like -- for 'Servant.API.Get.Get', 'Servant.API.Post.Post' and--- 'Servant.API.Put.Put', run in @EitherT (Int, String) IO ()@.+-- 'Servant.API.Put.Put', run in @EitherT ServantErr IO ()@. -- The 'Int' represents the status code and the 'String' a message -- to be returned. You can use 'Control.Monad.Trans.Either.left' to -- painlessly error out if the conditions for a successful deletion@@ -329,7 +329,7 @@ -- | When implementing the handler for a 'Get' endpoint, -- just like for 'Servant.API.Delete.Delete', 'Servant.API.Post.Post' -- and 'Servant.API.Put.Put', the handler code runs in the--- @EitherT (Int, String) IO@ monad, where the 'Int' represents+-- @EitherT ServantErr IO@ monad, where the 'Int' represents -- the status code and the 'String' a message, returned in case of -- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left' -- to quickly fail if some conditions are not met.@@ -425,7 +425,7 @@ -- > -- > server :: Server MyApi -- > server = viewReferer--- > where viewReferer :: Referer -> EitherT (Int, String) IO referer+-- > where viewReferer :: Referer -> EitherT ServantErr IO referer -- > viewReferer referer = return referer instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (Header sym a :> sublayout) where@@ -442,7 +442,7 @@ -- | When implementing the handler for a 'Post' endpoint, -- just like for 'Servant.API.Delete.Delete', 'Servant.API.Get.Get' -- and 'Servant.API.Put.Put', the handler code runs in the--- @EitherT (Int, String) IO@ monad, where the 'Int' represents+-- @EitherT ServantErr IO@ monad, where the 'Int' represents -- the status code and the 'String' a message, returned in case of -- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left' -- to quickly fail if some conditions are not met.@@ -523,7 +523,7 @@ -- | When implementing the handler for a 'Put' endpoint, -- just like for 'Servant.API.Delete.Delete', 'Servant.API.Get.Get' -- and 'Servant.API.Post.Post', the handler code runs in the--- @EitherT (Int, String) IO@ monad, where the 'Int' represents+-- @EitherT ServantErr IO@ monad, where the 'Int' represents -- the status code and the 'String' a message, returned in case of -- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left' -- to quickly fail if some conditions are not met.@@ -603,7 +603,7 @@ -- | When implementing the handler for a 'Patch' endpoint, -- just like for 'Servant.API.Delete.Delete', 'Servant.API.Get.Get' -- and 'Servant.API.Put.Put', the handler code runs in the--- @EitherT (Int, String) IO@ monad, where the 'Int' represents+-- @EitherT ServantErr IO@ monad, where the 'Int' represents -- the status code and the 'String' a message, returned in case of -- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left' -- to quickly fail if some conditions are not met.@@ -696,7 +696,7 @@ -- > -- > server :: Server MyApi -- > server = getBooksBy--- > where getBooksBy :: Maybe Text -> EitherT (Int, String) IO [Book]+-- > where getBooksBy :: Maybe Text -> EitherT ServantErr IO [Book] -- > getBooksBy Nothing = ...return all books... -- > getBooksBy (Just author) = ...return books by the given author... instance (KnownSymbol sym, FromText a, HasServer sublayout)@@ -735,7 +735,7 @@ -- > -- > server :: Server MyApi -- > server = getBooksBy--- > where getBooksBy :: [Text] -> EitherT (Int, String) IO [Book]+-- > where getBooksBy :: [Text] -> EitherT ServantErr IO [Book] -- > getBooksBy authors = ...return all books by these authors... instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (QueryParams sym a :> sublayout) where@@ -768,7 +768,7 @@ -- > -- > server :: Server MyApi -- > server = getBooks--- > where getBooks :: Bool -> EitherT (Int, String) IO [Book]+-- > where getBooks :: Bool -> EitherT ServantErr IO [Book] -- > getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument... instance (KnownSymbol sym, HasServer sublayout) => HasServer (QueryFlag sym :> sublayout) where@@ -810,7 +810,7 @@ -- > -- > server :: Server MyApi -- > server = getBooksBy--- > where getBooksBy :: Maybe Text -> EitherT (Int, String) IO [Book]+-- > where getBooksBy :: Maybe Text -> EitherT ServantErr IO [Book] -- > getBooksBy Nothing = ...return all books... -- > getBooksBy (Just author) = ...return books by the given author... instance (KnownSymbol sym, FromText a, HasServer sublayout)@@ -849,7 +849,7 @@ -- > -- > server :: Server MyApi -- > server = getBooksBy--- > where getBooksBy :: [Text] -> EitherT (Int, String) IO [Book]+-- > where getBooksBy :: [Text] -> EitherT ServantErr IO [Book] -- > getBooksBy authors = ...return all books by these authors... instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (MatrixParams sym a :> sublayout) where@@ -883,7 +883,7 @@ -- > -- > server :: Server MyApi -- > server = getBooks--- > where getBooks :: Bool -> EitherT (Int, String) IO [Book]+-- > where getBooks :: Bool -> EitherT ServantErr IO [Book] -- > getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument... instance (KnownSymbol sym, HasServer sublayout) => HasServer (MatrixFlag sym :> sublayout) where@@ -940,7 +940,7 @@ -- > -- > server :: Server MyApi -- > server = postBook--- > where postBook :: Book -> EitherT (Int, String) IO Book+-- > where postBook :: Book -> EitherT ServantErr IO Book -- > postBook book = ...insert into your db... instance ( AllCTUnrender list a, HasServer sublayout ) => HasServer (ReqBody list a :> sublayout) where
src/Servant/Utils/StaticFiles.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} -- | This module defines a sever-side handler that lets you serve static files. -- -- - 'serveDirectory' lets you serve anything that lives under a particular@@ -6,10 +7,13 @@ serveDirectory, ) where -import Filesystem.Path.CurrentOS (decodeString)+import System.FilePath (addTrailingPathSeparator) import Network.Wai.Application.Static (staticApp, defaultFileServerSettings) import Servant.API.Raw (Raw) import Servant.Server (Server)+#if !MIN_VERSION_wai_app_static(3,1,0)+import Filesystem.Path.CurrentOS (decodeString)+#endif -- | Serve anything under the specified directory as a 'Raw' endpoint. --@@ -32,5 +36,9 @@ -- handler in the last position, because /servant/ will try to match the handlers -- in order. serveDirectory :: FilePath -> Server Raw-serveDirectory documentRoot =- staticApp (defaultFileServerSettings (decodeString (documentRoot ++ "/")))+serveDirectory =+#if MIN_VERSION_wai_app_static(3,1,0)+ staticApp . defaultFileServerSettings . addTrailingPathSeparator+#else+ staticApp . defaultFileServerSettings . decodeString . addTrailingPathSeparator+#endif
test/Doctests.hs view
@@ -1,14 +1,18 @@ module Main where +import Data.List (isPrefixOf)+import System.Directory+import System.FilePath import System.FilePath.Find import Test.DocTest main :: IO () main = do files <- find always (extension ==? ".hs") "src"+ cabalMacrosFile <- getCabalMacrosFile doctest $ [ "-isrc" , "-optP-include"- , "-optPdist/build/autogen/cabal_macros.h"+ , "-optP" ++ cabalMacrosFile , "-XOverloadedStrings" , "-XFlexibleInstances" , "-XMultiParamTypeClasses"@@ -16,3 +20,12 @@ , "-XTypeOperators" ] ++ files +getCabalMacrosFile :: IO FilePath+getCabalMacrosFile = do+ contents <- getDirectoryContents "dist"+ let rest = "build" </> "autogen" </> "cabal_macros.h"+ return $ case filter ("dist-sandbox-" `isPrefixOf`) contents of+ [x] -> "dist" </> x </> rest+ [] -> "dist" </> rest+ xs -> error $ "ran doctests with multiple dist/dist-sandbox-xxxxx's: \n"+ ++ show xs ++ "\nTry cabal clean"