packages feed

descriptive 0.5.0 → 0.6.0

raw patch · 5 files changed

+58/−30 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Descriptive.Form: validate :: Text -> (a -> Maybe b) -> Consumer (Map Text Text) Form a -> Consumer (Map Text Text) Form b
+ Descriptive: validate :: d -> (forall m. MonadState s m => a -> m (Maybe b)) -> Consumer s d a -> Consumer s d b

Files

README.md view
@@ -20,6 +20,8 @@ data Consumer s d a ``` +## Making descriptive consumers+ To make a consumer, this combinator is used:  ``` haskell@@ -37,12 +39,15 @@ strings, a Map, a Vector, etc. You may or may not decide to modify the state during generation of the description and during parsing. +## Running descriptive consumers+ To use a consumer or describe what it does, these are used:  ``` haskell consume :: Consumer s d a -- ^ The consumer to run.         -> s -- ^ Initial state.         -> Result (Description d) a+ describe :: Consumer s d a -- ^ The consumer to run.          -> s -- ^ Initial state. Can be \"empty\" if you don't use it for               -- generating descriptions.@@ -56,12 +61,15 @@             => Consumer s d a -- ^ The consumer to run.             -> StateT s m (Result (Description d) a) runConsumer (Consumer _ m) = m+ runDescription :: Monad m                => Consumer s d a -- ^ The consumer to run.                -> StateT s m (Description d) runDescription (Consumer desc _) = desc ``` +## Descriptions+ A description is like this:  ``` haskell@@ -85,6 +93,24 @@ describeParser :: Description Text -> Text describeForm :: Description (Html ()) -> Html () describeArgs :: Description CmdArgs -> Text+```++## Wrapping++One can wrap up a consumer to alter either the description or the+parser or both, this can be used for wrapping labels, or adding+validation, things of that nature:++``` haskell+wrap :: (forall m. Monad m => StateT t m (Description d)+                           -> StateT s m (Description d))+     -- ^ Transform the description.+     -> (forall m. Monad m => StateT t m (Description d)+                           -> StateT t m (Result (Description d) a)+                           -> StateT s m (Result (Description d) b))+     -- ^ Transform the parser. Can re-run the parser as many times as desired.+     -> Consumer t d a+     -> Consumer s d b ```  See below for some examples of this library.
descriptive.cabal view
@@ -1,5 +1,5 @@ name:                descriptive-version:             0.5.0+version:             0.6.0 synopsis:            Self-describing consumers/parsers; forms, cmd-line args, JSON, etc. description:         Self-describing consumers/parsers. See the README.md for more information. It is currently EXPERIMENTAL. stability:           Experimental
src/Descriptive.hs view
@@ -21,7 +21,8 @@   ,Result(..)   -- * Combinators   ,consumer-  ,wrap)+  ,wrap+  ,validate)   where  import Control.Applicative@@ -267,3 +268,26 @@ wrap redescribe reparse (Consumer d p) =   Consumer (redescribe d)            (reparse d p)++-- | Add validation to a consumer.+validate :: d                                              -- ^ Description of what it expects.+         -> (forall m. MonadState s m => a -> m (Maybe b)) -- ^ Attempt to parse the value.+         -> Consumer s d a                                 -- ^ Consumer to add validation to.+         -> Consumer s d b                                 -- ^ A new validating consumer.+validate d' check =+  wrap (liftM wrapper)+       (\d p ->+          do s <- get+             r <- p+             case r of+               (Failed e) -> return (Failed e)+               (Continued e) ->+                 return (Continued (wrapper e))+               (Succeeded a) ->+                 do r' <- check a+                    case r' of+                      Nothing ->+                        do doc <- withStateT (const s) d+                           return (Continued (wrapper doc))+                      Just a' -> return (Succeeded a'))+  where wrapper = Wrap d'
src/Descriptive/Form.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE RankNTypes #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE FlexibleContexts #-} @@ -6,7 +7,6 @@ module Descriptive.Form   (-- * Combinators    input-  ,validate   -- * Description   ,Form (..)   )@@ -34,25 +34,3 @@                          Nothing -> Continued d                          Just a -> Succeeded a))   where d = Unit (Input name)---- | Validate a form input with a description of what's required.-validate :: Text -- ^ Description of what it expects.-         -> (a -> Maybe b) -- ^ Attempt to parse the value.-         -> Consumer (Map Text Text) Form a -- ^ Consumer to add validation to.-         -> Consumer (Map Text Text) Form b-validate d' check =-  wrap (liftM wrapper)-       (\d p ->-          do s <- get-             r <- p-             case r of-               (Failed e) -> return (Failed e)-               (Continued e) ->-                 return (Continued (wrapper e))-               (Succeeded a) ->-                 case check a of-                   Nothing ->-                     do doc <- withStateT (const s) d-                        return (Continued (wrapper doc))-                   Just a' -> return (Succeeded a'))-  where wrapper = Wrap (Constraint d')
src/test/Main.hs view
@@ -94,12 +94,12 @@                     [("password2","gob"),("password","go"),("token","woot")]) ==          Succeeded "woot")   where login =-          Form.validate-            "confirmed password (entered the same twice)"+          validate+            (Form.Constraint "confirmed password (entered the same twice)")             (\(x,y) ->-               if x == y-                  then Just y-                  else Nothing)+               return (if x == y+                          then Just y+                          else Nothing))             ((,) <$>              Form.input "password" <*>              Form.input "password2") <|>