yesod-json 1.1.2.2 → 1.2.0
raw patch · 3 files changed
+5/−221 lines, 3 filesdep −aesondep −attoparsec-conduitdep −blaze-builderdep ~basedep ~yesod-core
Dependencies removed: aeson, attoparsec-conduit, blaze-builder, bytestring, conduit, containers, hspec, safe, shakespeare-js, text, transformers, vector, wai, wai-extra, wai-test, yesod-json, yesod-routes
Dependency ranges changed: base, yesod-core
Files
- Yesod/Json.hs +1/−144
- test/Spec.hs +0/−47
- yesod-json.cabal +4/−30
Yesod/Json.hs view
@@ -1,144 +1,1 @@-{-# LANGUAGE TypeSynonymInstances, OverloadedStrings #-}-{-# LANGUAGE CPP #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Yesod.Json- ( -- * Convert from a JSON value- defaultLayoutJson- , jsonToRepJson-- -- * Convert to a JSON value- , parseJsonBody- , parseJsonBody_-- -- * Produce JSON values- , J.Value (..)- , object- , array- , (.=)-- -- * Convenience functions- , jsonOrRedirect- , acceptsJson- ) where--import Yesod.Handler (GHandler, waiRequest, lift, invalidArgs, redirect)-import Yesod.Content- ( ToContent (toContent), RepHtmlJson (RepHtmlJson), RepHtml (RepHtml)- , RepJson (RepJson), Content (ContentBuilder)- )-import Yesod.Core (defaultLayout, Yesod)-import Yesod.Widget (GWidget)-import Yesod.Routes.Class-import Control.Arrow (second)-import Control.Applicative ((<$>))-import Control.Monad (join)-import qualified Data.Aeson as J-import qualified Data.Aeson.Parser as JP-import Data.Aeson ((.=))-import qualified Data.Aeson.Encode as JE-import Data.Aeson.Encode (fromValue)-import Data.Conduit.Attoparsec (sinkParser)-import Data.Text (Text, pack)-import qualified Data.Vector as V-import Text.Julius (ToJavascript (..))-import Data.Text.Lazy.Builder (fromLazyText)-import Data.Text.Lazy.Encoding (decodeUtf8)-import Data.Text.Lazy.Builder (toLazyText)-import qualified Blaze.ByteString.Builder.Char.Utf8 as Blaze-import Data.Conduit-import Network.Wai (requestBody, requestHeaders)-import Network.Wai.Parse (parseHttpAccept)-import qualified Data.ByteString.Char8 as B8-import Safe (headMay)--#if !MIN_VERSION_yesod_core(1, 1, 5)-instance ToContent J.Value where- toContent = flip ContentBuilder Nothing- . Blaze.fromLazyText- . toLazyText- . fromValue-#endif---- | Provide both an HTML and JSON representation for a piece of--- data, using the default layout for the HTML output--- ('defaultLayout').------ /Since: 0.3.0/-defaultLayoutJson :: (Yesod master, J.ToJSON a)- => GWidget sub master () -- ^ HTML- -> a -- ^ JSON- -> GHandler sub master RepHtmlJson-defaultLayoutJson w json = do- RepHtml html' <- defaultLayout w- return $ RepHtmlJson html' $ toContent (J.toJSON json)---- | Wraps a data type in a 'RepJson'. The data type must--- support conversion to JSON via 'J.ToJSON'.------ /Since: 0.3.0/-jsonToRepJson :: J.ToJSON a => a -> GHandler sub master RepJson-jsonToRepJson = return . RepJson . toContent . J.toJSON---- | Parse the request body to a data type as a JSON value. The--- data type must support conversion from JSON via 'J.FromJSON'.--- If you want the raw JSON value, just ask for a @'J.Result'--- 'J.Value'@.------ /Since: 0.3.0/-parseJsonBody :: J.FromJSON a => GHandler sub master (J.Result a)-parseJsonBody = do- req <- waiRequest- eValue <- lift- $ runExceptionT- $ transPipe lift (requestBody req)- $$ sinkParser JP.value'- return $ case eValue of- Left e -> J.Error $ show e- Right value -> J.fromJSON value---- | Same as 'parseJsonBody', but return an invalid args response on a parse--- error.-parseJsonBody_ :: J.FromJSON a => GHandler sub master a-parseJsonBody_ = do- ra <- parseJsonBody- case ra of- J.Error s -> invalidArgs [pack s]- J.Success a -> return a--#if !MIN_VERSION_shakespeare_js(1, 0, 2)-instance ToJavascript J.Value where- toJavascript = fromLazyText . decodeUtf8 . JE.encode-#endif---- | Convert a list of pairs to an 'J.Object'.-object :: J.ToJSON a => [(Text, a)] -> J.Value-object = J.object . map (second J.toJSON)---- | Convert a list of values to an 'J.Array'.-array :: J.ToJSON a => [a] -> J.Value-array = J.Array . V.fromList . map J.toJSON---- | jsonOrRedirect simplifies the scenario where a POST handler sends a different--- response based on Accept headers:------ 1. 200 with JSON data if the client prefers--- @application\/json@ (e.g. AJAX, see 'acceptsJSON').------ 2. 3xx otherwise, following the PRG pattern.-jsonOrRedirect :: (Yesod master, J.ToJSON a)- => Route master -- ^ Redirect target- -> a -- ^ Data to send via JSON- -> GHandler sub master RepJson-jsonOrRedirect r j = do- q <- acceptsJson- if q then jsonToRepJson (J.toJSON j)- else redirect r---- | Returns @True@ if the client prefers @application\/json@ as--- indicated by the @Accept@ HTTP header.-acceptsJson :: Yesod master => GHandler sub master Bool-acceptsJson = maybe False ((== "application/json") . B8.takeWhile (/= ';'))- . join- . fmap (headMay . parseHttpAccept)- . lookup "Accept" . requestHeaders- <$> waiRequest+module Yesod.Json () where
− test/Spec.hs
@@ -1,47 +0,0 @@-{-# LANGUAGE OverloadedStrings, TemplateHaskell, QuasiQuotes, TypeFamilies, MultiParamTypeClasses #-}-import Yesod.Core-import Yesod.Json-import Test.Hspec-import qualified Data.Map as Map-import Network.Wai.Test-import Data.Text (Text)--data App = App--mkYesod "App" [parseRoutes|-/ HomeR GET-|]--instance Yesod App--getHomeR :: Handler RepPlain-getHomeR = do- val <- parseJsonBody_- case Map.lookup ("foo" :: Text) val of- Nothing -> invalidArgs ["foo not found"]- Just foo -> return $ RepPlain $ toContent (foo :: Text)--main :: IO ()-main = do- app <- toWaiApp App- hspec $ describe "Yesod.Json" $ do- it "parses valid content" $ flip runSession app $ do- sres <- srequest SRequest- { simpleRequest = defaultRequest- , simpleRequestBody = "{\"foo\":\"bar\"}"- }- assertStatus 200 sres- assertBody "bar" sres- it "400 for bad JSON" $ flip runSession app $ do- sres <- srequest SRequest- { simpleRequest = defaultRequest- , simpleRequestBody = "{\"foo\":\"bar\""- }- assertStatus 400 sres- it "400 for bad structure" $ flip runSession app $ do- sres <- srequest SRequest- { simpleRequest = defaultRequest- , simpleRequestBody = "{\"foo2\":\"bar\"}"- }- assertStatus 400 sres- assertBodyContains "foo not found" sres
yesod-json.cabal view
@@ -1,48 +1,22 @@ name: yesod-json-version: 1.1.2.2+version: 1.2.0 license: MIT license-file: LICENSE author: Michael Snoyman <michael@snoyman.com> maintainer: Michael Snoyman <michael@snoyman.com>-synopsis: Generate content for Yesod using the aeson package.+synopsis: Generate content for Yesod using the aeson package. (deprecated) category: Web, Yesod stability: Stable cabal-version: >= 1.8 build-type: Simple homepage: http://www.yesodweb.com/-description: Generate content for Yesod using the aeson package.+description: Since version 1.2 of Yesod, the functionality provided by this module is provided by yesod-core itself. You no longer need to use this package. library build-depends: base >= 4 && < 5- , yesod-core >= 1.1- , yesod-routes >= 1.1- , aeson >= 0.5- , text >= 0.8- , shakespeare-js >= 1.0- , vector >= 0.9- , containers >= 0.2- , blaze-builder- , attoparsec-conduit >= 0.5- , conduit >= 0.5- , transformers >= 0.2.2- , wai >= 1.3- , wai-extra >= 1.3- , bytestring >= 0.9- , safe >= 0.2+ , yesod-core >= 1.2 exposed-modules: Yesod.Json ghc-options: -Wall--test-suite tests- type: exitcode-stdio-1.0- main-is: Spec.hs- hs-source-dirs: test- build-depends: base- , wai-test- , hspec- , yesod-json- , yesod-core- , text- , containers source-repository head type: git