packages feed

scotty 0.9.0 → 0.9.1

raw patch · 9 files changed

+76/−44 lines, 9 filesdep +hspecdep −hspec2dep ~aesondep ~basedep ~blaze-builderPVP ok

version bump matches the API change (PVP)

Dependencies added: hspec

Dependencies removed: hspec2

Dependency ranges changed: aeson, base, blaze-builder, hspec-wai, monad-control

API changes (from Hackage documentation)

Files

Web/Scotty.hs view
@@ -171,12 +171,12 @@ setHeader = Trans.setHeader  -- | Set the body of the response to the given 'Text' value. Also sets \"Content-Type\"--- header to \"text/plain; charset=utf-8\".+-- header to \"text/plain; charset=utf-8\" if it has not already been set. text :: Text -> ActionM () text = Trans.text  -- | Set the body of the response to the given 'Text' value. Also sets \"Content-Type\"--- header to \"text/html; charset=utf-8\".+-- header to \"text/html; charset=utf-8\" if it has not already been set. html :: Text -> ActionM () html = Trans.html @@ -186,7 +186,7 @@ file = Trans.file  -- | Set the body of the response to the JSON encoding of the given value. Also sets \"Content-Type\"--- header to \"application/json; charset=utf-8\".+-- header to \"application/json; charset=utf-8\" if it has not already been set. json :: ToJSON a => a -> ActionM () json = Trans.json 
Web/Scotty/Action.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE CPP, OverloadedStrings, RankNTypes #-}+{-# LANGUAGE CPP               #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes        #-} module Web.Scotty.Action     ( addHeader     , body@@ -28,7 +30,7 @@     , runAction     ) where -import           Blaze.ByteString.Builder (fromLazyByteString)+import           Blaze.ByteString.Builder   (fromLazyByteString)  #if MIN_VERSION_mtl(2,2,1) import           Control.Monad.Except@@ -36,17 +38,17 @@ import           Control.Monad.Error #endif import           Control.Monad.Reader-import qualified Control.Monad.State as MS+import qualified Control.Monad.State        as MS -import qualified Data.Aeson as A-import qualified Data.ByteString.Char8 as B+import qualified Data.Aeson                 as A+import qualified Data.ByteString.Char8      as B import qualified Data.ByteString.Lazy.Char8 as BL-import qualified Data.CaseInsensitive as CI-import           Data.Default (def)-import           Data.Monoid (mconcat)-import qualified Data.Text as ST-import qualified Data.Text.Lazy as T-import           Data.Text.Lazy.Encoding (encodeUtf8)+import qualified Data.CaseInsensitive       as CI+import           Data.Default               (def)+import           Data.Monoid                (mconcat)+import qualified Data.Text                  as ST+import qualified Data.Text.Lazy             as T+import           Data.Text.Lazy.Encoding    (encodeUtf8)  import           Network.HTTP.Types import           Network.Wai@@ -151,7 +153,7 @@ jsonData :: (A.FromJSON a, ScottyError e, Monad m) => ActionT e m a jsonData = do     b <- body-    maybe (raise $ stringError $ "jsonData - no parse: " ++ BL.unpack b) return $ A.decode b+    either (\e -> raise $ stringError $ "jsonData - no parse: " ++ e ++ ". Data was:" ++ BL.unpack b) return $ A.eitherDecode b  -- | Get a parameter. First looks in captures, then form data, then query parameters. --@@ -186,6 +188,7 @@ instance Parsable T.Text where parseParam = Right instance Parsable ST.Text where parseParam = Right . T.toStrict instance Parsable B.ByteString where parseParam = Right . lazyTextToStrictByteString+instance Parsable BL.ByteString where parseParam = Right . encodeUtf8 -- | Overrides default 'parseParamList' to parse String. instance Parsable Char where     parseParam t = case T.unpack t of@@ -215,7 +218,7 @@ -- | Useful for creating 'Parsable' instances for things that already implement 'Read'. Ex: -- -- > instance Parsable Int where parseParam = readEither-readEither :: (Read a) => T.Text -> Either T.Text a+readEither :: Read a => T.Text -> Either T.Text a readEither t = case [ x | (x,"") <- reads (T.unpack t) ] of                 [x] -> Right x                 []  -> Left "readEither: no parse"@@ -225,27 +228,37 @@ status :: (ScottyError e, Monad m) => Status -> ActionT e m () status = ActionT . MS.modify . setStatus +-- Not exported, but useful in the functions below.+changeHeader :: (ScottyError e, Monad m)+             => (CI.CI B.ByteString -> B.ByteString -> [(HeaderName, B.ByteString)] -> [(HeaderName, B.ByteString)])+             -> T.Text -> T.Text -> ActionT e m ()+changeHeader f k = ActionT+                 . MS.modify+                 . setHeaderWith+                 . f (CI.mk $ lazyTextToStrictByteString k)+                 . lazyTextToStrictByteString+ -- | Add to the response headers. Header names are case-insensitive. addHeader :: (ScottyError e, Monad m) => T.Text -> T.Text -> ActionT e m ()-addHeader k v = ActionT . MS.modify $ setHeaderWith $ add (CI.mk $ lazyTextToStrictByteString k) (lazyTextToStrictByteString v)+addHeader = changeHeader add  -- | Set one of the response headers. Will override any previously set value for that header. -- Header names are case-insensitive. setHeader :: (ScottyError e, Monad m) => T.Text -> T.Text -> ActionT e m ()-setHeader k v = ActionT . MS.modify $ setHeaderWith $ replace (CI.mk $ lazyTextToStrictByteString k) (lazyTextToStrictByteString v)+setHeader = changeHeader replace  -- | Set the body of the response to the given 'T.Text' value. Also sets \"Content-Type\"--- header to \"text/plain; charset=utf-8\".+-- header to \"text/plain; charset=utf-8\" if it has not already been set. text :: (ScottyError e, Monad m) => T.Text -> ActionT e m () text t = do-    setHeader "Content-Type" "text/plain; charset=utf-8"+    changeHeader addIfNotPresent "Content-Type" "text/plain; charset=utf-8"     raw $ encodeUtf8 t  -- | Set the body of the response to the given 'T.Text' value. Also sets \"Content-Type\"--- header to \"text/html; charset=utf-8\".+-- header to \"text/html; charset=utf-8\" if it has not already been set. html :: (ScottyError e, Monad m) => T.Text -> ActionT e m () html t = do-    setHeader "Content-Type" "text/html; charset=utf-8"+    changeHeader addIfNotPresent "Content-Type" "text/html; charset=utf-8"     raw $ encodeUtf8 t  -- | Send a file as the response. Doesn't set the \"Content-Type\" header, so you probably@@ -254,10 +267,10 @@ file = ActionT . MS.modify . setContent . ContentFile  -- | Set the body of the response to the JSON encoding of the given value. Also sets \"Content-Type\"--- header to \"application/json; charset=utf-8\".+-- header to \"application/json; charset=utf-8\" if it has not already been set. json :: (A.ToJSON a, ScottyError e, Monad m) => a -> ActionT e m () json v = do-    setHeader "Content-Type" "application/json; charset=utf-8"+    changeHeader addIfNotPresent "Content-Type" "application/json; charset=utf-8"     raw $ A.encode v  -- | Set the body of the response to a Source. Doesn't set the
Web/Scotty/Internal/Types.hs view
@@ -150,21 +150,21 @@  instance ScottyError e => MonadTransControl (ActionT e) where #if MIN_VERSION_mtl(2,2,1)-     newtype StT (ActionT e) a = StAction {unStAction :: StT (StateT ScottyResponse) (StT (ReaderT ActionEnv) (StT (ExceptT (ActionError e)) a))}+     type StT (ActionT e) a = StT (StateT ScottyResponse) (StT (ReaderT ActionEnv) (StT (ExceptT (ActionError e)) a)) #else-     newtype StT (ActionT e) a = StAction {unStAction :: StT (StateT ScottyResponse) (StT (ReaderT ActionEnv) (StT (ErrorT (ActionError e)) a))}+     type StT (ActionT e) a = StT (StateT ScottyResponse) (StT (ReaderT ActionEnv) (StT (ErrorT (ActionError e)) a)) #endif      liftWith = \f ->         ActionT $  liftWith $ \run  ->                    liftWith $ \run' ->                    liftWith $ \run'' ->-                   f $ liftM StAction . run'' . run' . run . runAM-     restoreT = ActionT . restoreT . restoreT . restoreT . liftM unStAction+                   f $ run'' . run' . run . runAM+     restoreT = ActionT . restoreT . restoreT . restoreT  instance (ScottyError e, MonadBaseControl b m) => MonadBaseControl b (ActionT e m) where-    newtype StM (ActionT e m) a = STMAction {unStMActionT :: ComposeSt (ActionT e) m a}-    liftBaseWith = defaultLiftBaseWith STMAction-    restoreM     = defaultRestoreM   unStMActionT+    type StM (ActionT e m) a = ComposeSt (ActionT e) m a+    liftBaseWith = defaultLiftBaseWith+    restoreM     = defaultRestoreM  ------------------ Scotty Routes -------------------- data RoutePattern = Capture   Text
Web/Scotty/Route.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, FlexibleContexts, FlexibleInstances, LambdaCase,+{-# LANGUAGE CPP, FlexibleContexts, FlexibleInstances,              OverloadedStrings, RankNTypes, ScopedTypeVariables #-} module Web.Scotty.Route     ( get, post, put, delete, patch, addroute, matchAny, notFound,@@ -124,9 +124,9 @@         Just rbt -> do             mvar <- liftIO $ newMVar bl -- MVar is a bit of a hack so we don't have to inline                                         -- large portions of Network.Wai.Parse-            let provider = takeMVar mvar >>= \case-                                                []     -> putMVar mvar [] >> return B.empty-                                                (b:bs) -> putMVar mvar bs >> return b+            let provider = modifyMVar mvar $ \bsold -> case bsold of+                                                []     -> return ([], B.empty)+                                                (b:bs) -> return (bs, b)             liftIO $ Parse.sinkRequestBody s rbt provider  mkEnv :: forall m. MonadIO m => Request -> [Param] -> m ActionEnv
Web/Scotty/Trans.hs view
@@ -89,7 +89,7 @@            -> n Application scottyAppT runM runActionToIO defs = do     s <- runM $ execStateT (runS defs) def-    let rapp = \ req callback -> runActionToIO (foldl (flip ($)) notFoundApp (routes s) req) >>= callback+    let rapp req callback = runActionToIO (foldl (flip ($)) notFoundApp (routes s) req) >>= callback     return $ foldl (flip ($)) rapp (middlewares s)  notFoundApp :: Monad m => Scotty.Application m
Web/Scotty/Util.hs view
@@ -7,6 +7,7 @@     , mkResponse     , replace     , add+    , addIfNotPresent     ) where  import Network.Wai@@ -46,8 +47,15 @@           h = srHeaders sr  -- Note: we assume headers are not sensitive to order here (RFC 2616 specifies they are not)-replace :: (Eq a) => a -> b -> [(a,b)] -> [(a,b)]-replace k v m = add k v $ filter ((/= k) . fst) m+replace :: Eq a => a -> b -> [(a,b)] -> [(a,b)]+replace k v = add k v . filter ((/= k) . fst) -add :: (Eq a) => a -> b -> [(a,b)] -> [(a,b)]+add :: Eq a => a -> b -> [(a,b)] -> [(a,b)] add k v m = (k,v):m++addIfNotPresent :: Eq a => a -> b -> [(a,b)] -> [(a,b)]+addIfNotPresent k v = go+    where go []         = [(k,v)]+          go l@((x,y):r)+            | x == k    = l+            | otherwise = (x,y) : go r
changelog.md view
@@ -1,3 +1,13 @@+## 0.9.1++* `Parsable` instance for lazy bytestrings++* `jsonData` now returns decoding error message++* text/html/json only set Content-Type header when not already set++* Bump `monad-control` to 1.0.0.0+ ## 0.9.0  * Add `charset=utf-8` to `Content-Type` for `text`, `html` and `json`
examples/basic.hs view
@@ -63,6 +63,7 @@     -- Files are streamed directly to the client.     get "/404" $ file "404.html" +    -- You can stop execution of this action and keep pattern matching routes.     get "/random" $ do         next         redirect "http://www.we-never-go-here.com"
scotty.cabal view
@@ -1,5 +1,5 @@ Name:                scotty-Version:             0.9.0+Version:             0.9.1 Synopsis:            Haskell web framework inspired by Ruby's Sinatra, using WAI and Warp Homepage:            https://github.com/scotty-web/scotty Bug-reports:         https://github.com/scotty-web/scotty/issues@@ -76,9 +76,9 @@                        data-default     >= 0.5.3    && < 0.6,                        http-types       >= 0.8.2    && < 0.9,                        mtl              >= 2.1.2    && < 2.3,-                       monad-control    >= 0.3.2.3  && < 0.4,+                       monad-control    >= 1.0.0.0  && < 1.1,                        regex-compat     >= 0.95.1   && < 0.96,-                       text             >= 0.11.3.1 && < 1.2,+                       text             >= 0.11.3.1 && < 1.3,                        transformers     >= 0.3.0.0  && < 0.5,                        transformers-base >= 0.4.1   && < 0.5,                        wai              >= 3.0.0    && < 3.1,@@ -98,8 +98,8 @@                        http-types,                        lifted-base,                        wai,-                       hspec2,-                       hspec-wai >= 0.3.0,+                       hspec == 2.*,+                       hspec-wai >= 0.5,                        scotty   GHC-options:         -Wall -fno-warn-orphans