-- | Module providing a snap backend for the digestive-functors library -- {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} module Text.Digestive.Forms.Snap ( SnapInput , SnapForm , snapEnvironment , eitherSnapForm , runViewSnapForm ) where import Control.Applicative ((<$>)) import Control.Monad (liftM) import Data.ByteString as SB import Data.ByteString.UTF8 as SB (toString, fromString) import Snap.Types import Text.Digestive.Forms (FormInput (..)) import Text.Digestive.Types (Form (..), Environment (..), viewForm, runViewForm, eitherForm) newtype SnapInput = SnapInput {unSnapInput :: SB.ByteString} instance FormInput SnapInput () where getInputStrings = return . SB.toString . unSnapInput getInputFile = const Nothing -- | Simplification of the `Form` type, instantiated to Snap -- type SnapForm m = Form m SnapInput -- | Environment that will fetch input from the parameters parsed by Snap -- snapEnvironment :: (MonadSnap m) => Environment m SnapInput snapEnvironment = Environment $ \id' -> do input' <- getParam (SB.fromString $ show id') return $ SnapInput <$> input' -- | Run a snap form -- -- * When we are responding to a GET request, you will simply receive the form -- as a view -- -- * When we are responding to another request method, the form data will be -- used. When errors occur, you will receive the form as a view, otherwise, -- you will get the actual result -- eitherSnapForm :: (MonadSnap m) => SnapForm m e v a -- ^ Form -> String -- ^ Form name -> m (Either v a) -- ^ Result eitherSnapForm form name = do method' <- rqMethod <$> getRequest case method' of GET -> liftM Left $ viewForm form name _ -> eitherForm form name snapEnvironment ------------------------------------------------------------------------------- -- | Render a snap form using the current Params runViewSnapForm :: (MonadSnap m) => SnapForm m e v a -> String -> m (v, Maybe a) runViewSnapForm form name = runViewForm form name snapEnvironment