module Yesod.Form.JSON
(
runJSONForm
, jsonField
)
where
import Prelude
import Data.Aeson (eitherDecode, encode)
import Yesod.Form.Types
import Data.Text (Text, pack)
import Control.Applicative (Applicative (..))
import Yesod.Core
import Control.Monad (liftM)
import qualified Data.Map as Map
import Data.Maybe (fromMaybe, catMaybes)
import Control.Arrow ((***))
import Yesod.Form.Input (FormInput(..))
import qualified Data.HashMap.Strict as HM (toList)
import Yesod.Form.Functions (parseHelper)
import Data.Text.Encoding (encodeUtf8, decodeUtf8)
import qualified Data.ByteString.Lazy as B (fromStrict, toStrict)
runJSONForm :: MonadHandler m => FormInput m a -> m a
runJSONForm (FormInput f) = do
obj <- requireJsonBody
let env = toEnv obj
m <- getYesod
l <- languages
emx <- f m l env Map.empty
case emx of
Left errs -> invalidArgs $ errs []
Right x -> return x
jsonField :: (Monad m, FromJSON a) => RenderMessage (HandlerSite m) FormMessage => Field m a
jsonField = Field (parseHelper helper) undefined undefined
where
helper json = case (eitherDecode . B.fromStrict . encodeUtf8) json of
Left err -> Left $ MsgInvalidEntry $ pack err
Right v -> Right v
toEnv :: Value -> Env
toEnv (Object obj) =
let l = map json2Text $ HM.toList obj
in Map.fromList $ catMaybes l
where
json2Text (name, obj@(Object _)) = Just $ (name, [(decodeUtf8 . B.toStrict . encode) obj])
json2Text (name, arr@(Array _)) = Just $ (name, [(decodeUtf8 . B.toStrict . encode) arr])
json2Text (name, String str) = Just $ (name, [str])
json2Text (name, Number n) = Just $ (name, [pack $ show n])
json2Text (name, Bool b) = Just $ (name, [pack $ show b])
toEnv _ = Map.empty