Merge pull request #196 from meteficha/yesod-json-more-generic

More generic types on Yesod.Json using FromJSON/ToJSON.
This commit is contained in:
Michael Snoyman 2011-12-31 21:00:11 -08:00
commit 1c23a7d03f

View File

@ -5,8 +5,10 @@ module Yesod.Json
( -- * Convert from a JSON value
defaultLayoutJson
, jsonToRepJson
-- * Convert to a JSON value
, parseJsonBody
-- * Produce JSON values
, J.Value (..)
, object
@ -20,6 +22,7 @@ import Yesod.Content
)
import Yesod.Core (defaultLayout, Yesod)
import Yesod.Widget (GWidget)
import Control.Arrow (second)
import qualified Data.Aeson as J
import qualified Data.Aeson.Encode as JE
import Data.Aeson.Encode (fromValue)
@ -40,35 +43,44 @@ instance ToContent J.Value where
. toLazyText
. fromValue
-- | Provide both an HTML and JSON representation for a piece of data, using
-- the default layout for the HTML output ('defaultLayout').
defaultLayoutJson :: Yesod master
=> GWidget sub master ()
-> J.Value
-- | 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 json
return $ RepHtmlJson html' $ toContent (J.toJSON json)
-- | Wraps the 'Content' generated by 'jsonToContent' in a 'RepJson'.
jsonToRepJson :: J.Value -> GHandler sub master RepJson
jsonToRepJson = return . RepJson . toContent
-- | Parse the request body as a JSON value.
-- | Wraps a data type in a 'RepJson'. The data type must
-- support conversion to JSON via 'J.ToJSON'.
--
-- /Since: 0.2.3/
parseJsonBody :: GHandler sub master J.Value
-- /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
lift $ requestBody req $$ sinkParser J.json'
fmap J.fromJSON $ lift $ requestBody req $$ sinkParser J.json'
instance ToJavascript J.Value where
toJavascript = fromLazyText . decodeUtf8 . JE.encode
-- | Convert a list of pairs to an 'J.Object'.
object :: [(Text, J.Value)] -> J.Value
object = 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.Value] -> J.Value
array = J.Array . V.fromList
array :: J.ToJSON a => [a] -> J.Value
array = J.Array . V.fromList . map J.toJSON