89 lines
2.5 KiB
Haskell
89 lines
2.5 KiB
Haskell
{-# LANGUAGE TypeSynonymInstances #-}
|
|
{-# LANGUAGE CPP #-}
|
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
|
module Yesod.Json
|
|
( -- * Convert from a JSON value
|
|
defaultLayoutJson
|
|
, jsonToRepJson
|
|
-- * Convert to a JSON value
|
|
, parseJsonBody
|
|
-- * Compatibility wrapper for old API
|
|
, Json
|
|
, jsonScalar
|
|
, jsonList
|
|
, jsonMap
|
|
) where
|
|
|
|
import Yesod.Handler (GHandler)
|
|
import Yesod.Content
|
|
( ToContent (toContent), RepHtmlJson (RepHtmlJson), RepHtml (RepHtml)
|
|
, RepJson (RepJson), Content (ContentBuilder)
|
|
)
|
|
import Yesod.Core (defaultLayout, Yesod)
|
|
import Yesod.Widget (GWidget)
|
|
import qualified Data.Aeson as J
|
|
import qualified Data.Aeson.Encode as JE
|
|
import Data.Aeson.Encode (fromValue)
|
|
import Data.Attoparsec.Enumerator (iterParser)
|
|
import Data.Text (pack)
|
|
import Control.Arrow (first)
|
|
import Control.Monad.Trans.Class (lift)
|
|
#if MIN_VERSION_aeson(0, 4, 0)
|
|
import Data.HashMap.Strict (fromList)
|
|
#else
|
|
import Data.Map (fromList)
|
|
#endif
|
|
import qualified Data.Vector as V
|
|
import Text.Julius (ToJavascript (..))
|
|
import Data.Text.Lazy.Builder (fromLazyText)
|
|
import Data.Text.Lazy.Encoding (decodeUtf8)
|
|
#if MIN_VERSION_aeson(0, 5, 0)
|
|
import Data.Text.Lazy.Builder (toLazyText)
|
|
import qualified Blaze.ByteString.Builder.Char.Utf8 as Blaze
|
|
#endif
|
|
|
|
instance ToContent J.Value where
|
|
#if MIN_VERSION_aeson(0, 5, 0)
|
|
toContent = flip ContentBuilder Nothing
|
|
. Blaze.fromLazyText
|
|
. toLazyText
|
|
. fromValue
|
|
#else
|
|
toContent = flip ContentBuilder Nothing . fromValue
|
|
#endif
|
|
|
|
-- | 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
|
|
-> GHandler sub master RepHtmlJson
|
|
defaultLayoutJson w json = do
|
|
RepHtml html' <- defaultLayout w
|
|
return $ RepHtmlJson html' $ toContent 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.
|
|
--
|
|
-- /Since: 0.2.3/
|
|
parseJsonBody :: GHandler sub master J.Value
|
|
parseJsonBody = lift $ iterParser J.json'
|
|
|
|
|
|
type Json = J.Value
|
|
|
|
jsonScalar :: String -> Json
|
|
jsonScalar = J.String . pack
|
|
|
|
jsonList :: [Json] -> Json
|
|
jsonList = J.Array . V.fromList
|
|
|
|
jsonMap :: [(String, Json)] -> Json
|
|
jsonMap = J.Object . fromList . map (first pack)
|
|
|
|
instance ToJavascript J.Value where
|
|
toJavascript = fromLazyText . decodeUtf8 . JE.encode
|