packages feed

formlets 0.2.1 → 0.3

raw patch · 3 files changed

+53/−30 lines, 3 filesdep +bytestringPVP ok

version bump matches the API change (PVP)

Dependencies added: bytestring

API changes (from Hackage documentation)

+ Text.Formlets: ContentType :: String -> String -> [(String, String)] -> ContentType
+ Text.Formlets: File :: ByteString -> String -> ContentType -> File
+ Text.Formlets: MultiPart :: FormContentType
+ Text.Formlets: UrlEncoded :: FormContentType
+ Text.Formlets: content :: File -> ByteString
+ Text.Formlets: contentType :: File -> ContentType
+ Text.Formlets: ctParameters :: ContentType -> [(String, String)]
+ Text.Formlets: ctSubtype :: ContentType -> String
+ Text.Formlets: ctType :: ContentType -> String
+ Text.Formlets: data ContentType
+ Text.Formlets: data File
+ Text.Formlets: data FormContentType
+ Text.Formlets: fileName :: File -> String
+ Text.Formlets: inputFile :: (String -> xml) -> Form xml File
+ Text.Formlets: instance Eq ContentType
+ Text.Formlets: instance Eq File
+ Text.Formlets: instance Eq FormContentType
+ Text.Formlets: instance Read ContentType
+ Text.Formlets: instance Read File
+ Text.Formlets: instance Read FormContentType
+ Text.Formlets: instance Show ContentType
+ Text.Formlets: instance Show File
+ Text.Formlets: instance Show FormContentType
+ Text.XHtml.Strict.Formlets: file :: XHtmlForm File
- Text.Formlets: runFormState :: Env -> Form xml a -> (Collector (Failing a), xml)
+ Text.Formlets: runFormState :: Env -> Form xml a -> (Collector (Failing a), xml, FormContentType)
- Text.Formlets: type Env = [(String, String)]
+ Text.Formlets: type Env = [(String, Either String File)]

Files

Text/Formlets.hs view
@@ -1,8 +1,9 @@-module Text.Formlets ( input', fmapFst+module Text.Formlets ( input', inputFile, fmapFst                      , check, ensure, ensures                      , runFormState                       , xml, plug                      , Env , Form , Plus (..)+                     , File (..), ContentType (..), FormContentType (..)                      )                      where @@ -10,7 +11,23 @@ import Control.Applicative.Error import Control.Applicative.State import Data.Maybe (isJust)+import qualified Data.ByteString.Lazy as BS +-- Form stuff+type Env = [(String, Either String File)]+type FormState = Names+type Names = Integer+type Name = String+type Collector a = Env -> a+data FormContentType = UrlEncoded | MultiPart deriving (Eq, Show, Read)+newtype Form xml a = Form { deform :: Env -> State FormState (Collector (Failing a), xml, FormContentType) }+data File = File {content :: BS.ByteString, fileName :: String, contentType :: ContentType} deriving (Eq, Show, Read)+data ContentType = ContentType { ctType :: String+                               , ctSubtype :: String+                               , ctParameters :: [(String, String)]+                               }+                               deriving (Eq, Show, Read)+ class Plus a where   zero :: a   plus :: a -> a -> a@@ -36,64 +53,67 @@ -- | Helper function for genereting input components based forms. input' :: (String -> String -> xml) -> Maybe String -> Form xml String input' i defaultValue = Form $ \env -> mkInput env <$> freshName-   where mkInput env name = (Success . (`queryParam` (name)),-                             i name (value name env))-         value name env = maybe (maybe "" id defaultValue) id (lookup name env)+   where mkInput env name = (fromLeft name . (lookup name),+                             i name (value name env), UrlEncoded)+         value name env = maybe (maybe "" id defaultValue) fromLeft' (lookup name env)+         fromLeft' (Left x) = x+         fromLeft' _        = ""+         fromLeft n Nothing         = Failure [n ++ " is not in the data"]+         fromLeft n (Just (Left x)) = Success x+         fromLeft n _               = Failure [n ++ " is a file."] +inputFile :: (String -> xml) -> Form xml File+inputFile i = Form $ \env -> mkInput env <$> freshName+  where  mkInput env name    = (fromRight name . (lookup name), i name, MultiPart)+         fromRight n Nothing          = Failure [n ++ " is not in the data"]+         fromRight n (Just (Right x)) = Success x+         fromRight n _                = Failure [n ++ " is not a file"]++ -- | Runs the form state runFormState :: Env             -- ^ A previously filled environment (may be empty)              -> Form xml a      -- ^ The form-             -> (Collector (Failing a), xml)+             -> (Collector (Failing a), xml, FormContentType) runFormState e (Form f) = evalState (f e) 0  -- | Add additional validation to an already validated component check :: Form xml a -> (a -> Failing b) -> Form xml b check (Form frm) f = Form $ \e -> checker (frm e)- where checker = fmap $ fmapFst (f' .)+ where checker = fmap $ fmapFst3 (f' .)        f' (Failure x) = Failure x        f' (Success x) = f x ---- Form stuff-type Env = [(String, String)]-type FormState = Names-type Names = Integer-type Name = String -queryParam :: Env -> Name -> String-queryParam env name = case (name `lookup` env) of-                           Nothing -> error $ "Couldn't find " ++ name-                           Just x  -> x---newtype Form xml a = Form { deform :: Env -> State FormState (Collector (Failing a), xml) }- instance Functor (Form xml) where-  fmap f (Form a) = Form $ \env -> (fmap . fmapFst . fmap . fmap) f (a env)--fmapFst f (a, b) = (f a, b)+  fmap f (Form a) = Form $ \env -> (fmap . fmapFst3 . fmap . fmap) f (a env) -type Collector a = Env -> a+fmapFst  f (a, b)    = (f a, b)+fmapFst3 f (a, b, c) = (f a, b, c)  instance Plus xml => Applicative (Form xml) where    pure = pureF    (<*>) = applyF  pureF :: Plus xml => a -> Form xml a-pureF v = Form $ \env -> pure (const (Success v), zero) -- K+pureF v = Form $ \env -> pure (const (Success v), zero, UrlEncoded)  applyF :: Plus xml => Form xml (a -> b) -> Form xml a -> Form xml b (Form f) `applyF` (Form v) = Form $ \env -> pure combine <*> f env <*> v env-  where combine (v1, xml1) (v2, xml2) = (\e -> v1 e <*> v2 e, xml1 `plus` xml2)+  where combine (v1, xml1, t1) (v2, xml2, t2) = (\e -> v1 e <*> v2 e, xml1 `plus` xml2, t1 `orT` t2) +orT UrlEncoded x = x+orT x UrlEncoded = x+orT x y          = x + -- | Component: just some xml xml :: xml -> Form xml ()-xml x = Form $ \env -> pure (const $ Success (), x)+xml x = Form $ \env -> pure (const $ Success (), x, UrlEncoded)  -- | Transform the XML component plug :: Plus xml => (xml -> xml) -> Form xml a -> Form xml a f `plug` (Form m) = Form $ \env -> pure plugin <*> m env-   where plugin (c, x) = (c, f x)+   where plugin (c, x, t) = (c, f x, t)  ----------------------------------------------- -- Private methods
Text/XHtml/Strict/Formlets.hs view
@@ -1,4 +1,4 @@-module Text.XHtml.Strict.Formlets ( input, textarea, password+module Text.XHtml.Strict.Formlets ( input, textarea, password, file                                   , hidden, inputInteger, radio, enumRadio                                   , XHtmlForm                                   , module Text.Formlets@@ -33,6 +33,9 @@ -- | A validated integer component inputInteger :: Maybe Integer -> XHtmlForm Integer inputInteger x = input (fmap show x) `check` asInteger ++file :: XHtmlForm File+file = inputFile X.afile  -- | A radio choice radio :: [(String, String)] -> Maybe String -> XHtmlForm String
formlets.cabal view
@@ -1,5 +1,5 @@ Name:            formlets-Version:         0.2.1+Version:         0.3 Synopsis:        Formlets implemented in Haskell Description:     A modular way to build forms based on applicative functors, as                  described in:@@ -17,4 +17,4 @@ Exposed-Modules:   Text.Formlets                  , Text.XHtml.Strict.Formlets Build-Type:      Simple-Build-Depends:   base, haskell98, mtl, xhtml, applicative-extras+Build-Depends:   base, haskell98, mtl, xhtml, applicative-extras, bytestring