packages feed

descriptive 0.0.0 → 0.0.1

raw patch · 7 files changed

+141/−88 lines, 7 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Descriptive: runConsumer :: Consumer s d a -> s -> (Either (Description d) a, s)
+ Descriptive: runDescription :: Consumer s d a -> s -> (Description d, s)
- Descriptive: consume :: Consumer s d a -> s -> (Either (Description d) a, s)
+ Descriptive: consume :: Consumer s d a -> s -> Either (Description d) a
- Descriptive: describe :: Consumer s d a -> s -> (Description d, s)
+ Descriptive: describe :: Consumer s d a -> s -> Description d

Files

descriptive.cabal view
@@ -1,5 +1,5 @@ name:                descriptive-version:             0.0.0+version:             0.0.1 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
@@ -8,14 +8,20 @@ -- | Descriptive parsers.  module Descriptive-  (Description(..)+  (-- * Consuming and describing+   consume+  ,describe+   -- * Lower-level runners+  ,runConsumer+  ,runDescription+  -- * Types+  ,Description(..)   ,Bound(..)   ,Consumer(..)+  -- * Combinators   ,consumer   ,wrap-  ,sequencing-  ,consume-  ,describe)+  ,sequencing)   where  import Control.Applicative@@ -24,6 +30,35 @@ import Data.Monoid  --------------------------------------------------------------------------------+-- Running++-- | Run a consumer.+consume :: Consumer s d a -- ^ The consumer to run.+        -> s -- ^ Initial state.+        -> Either (Description d) a+consume (Consumer _ m) = fst . m++-- | Describe a consumer.+describe :: Consumer s d a -- ^ The consumer to run.+         -> s -- ^ Initial state. Can be empty if you don't use it for+              -- generating descriptions.+         -> Description d -- ^ A description and resultant state.+describe (Consumer desc _) = fst . desc++-- | Run a consumer.+runConsumer :: Consumer s d a -- ^ The consumer to run.+            -> s -- ^ Initial state.+            -> (Either (Description d) a,s)+runConsumer (Consumer _ m) = m++-- | Describe a consumer.+runDescription :: Consumer s d a -- ^ The consumer to run.+               -> s -- ^ Initial state. Can be empty if you don't use it for+                    -- generating descriptions.+               -> (Description d,s) -- ^ A description and resultant state.+runDescription (Consumer desc _) = desc++-------------------------------------------------------------------------------- -- Types  -- | Description of a consumable thing.@@ -92,12 +127,12 @@                 in (Or d1 d2,s''))              (\s ->                 case consumerParse a s of-                  (Left e1,s') ->-                    case consumerParse b s' of-                      (Left e2,s'') ->-                        (Left (Or e1 e2),s'')-                      (Right a2,s'') ->-                        (Right a2,s'')+                  (Left e1,_) ->+                    case consumerParse b s of+                      (Left e2,s') ->+                        (Left (Or e1 e2),s')+                      (Right a2,s') ->+                        (Right a2,s')                   (Right a1,s') -> (Right a1,s'))   some = sequenceHelper 1   many = sequenceHelper 0@@ -143,20 +178,22 @@ -- Combinators  -- | Make a consumer.-consumer :: (s -> (Description d,s)) -> (s -> (Either (Description d) a,s)) -> Consumer s d a+consumer :: (s -> (Description d,s)) -- ^ Produce description based on the state.+         -> (s -> (Either (Description d) a,s)) -- ^ Parse the state and maybe transform it if desired.+         -> Consumer s d a consumer d p =   Consumer d p  -- | Wrap a consumer with another consumer.-wrap :: (s -> (t -> (Description d,t)) -> (Description d,s))-     -> (s -> (t -> (Description d,t)) -> (t -> (Either (Description d) a,t)) -> (Either (Description d) b,s))-     -> Consumer t d a-     -> Consumer s d b+wrap :: (s -> (t -> (Description d,t)) -> (Description d,s)) -- ^ Transformer the description.+     -> (s -> (t -> (Description d,t)) -> (t -> (Either (Description d) a,t)) -> (Either (Description d) b,s)) -- ^ Transform the parser. Can re-run the parser if desired.+     -> Consumer t d a -- ^ The consumer to transform.+     -> Consumer s d b -- ^ A new consumer with a potentially new state type. wrap redescribe reparse (Consumer d p) =   Consumer (\s -> redescribe s d)            (\s -> reparse s d p) --- | Compose contiguous items into one sequence.+-- | Compose contiguous items into one sequence. Similar to 'sequenceA'. sequencing :: [Consumer d s a] -> Consumer d s [a] sequencing =   wrap (\s d ->@@ -169,14 +206,3 @@         se x = [x]         go (x:xs) = (:) <$> x <*> sequencing xs         go [] = mempty------------------------------------------------------------------------------------- Running---- | Run a consumer.-consume :: Consumer s d a -> s -> (Either (Description d) a,s)-consume (Consumer _ m) = m---- | Describe a consumer.-describe :: Consumer s d a -> s -> (Description d,s)-describe (Consumer desc _) = desc
src/Descriptive/Char.hs view
@@ -3,20 +3,6 @@ {-# LANGUAGE FlexibleContexts #-}  -- | Consuming form a list of characters.------ Examples:------ λ> describe (zeroOrMore (char 'k') <> string "abc") []--- (And (Bounded 0 UnlimitedBound (Unit "k")) (And (Unit "a") (And (Unit "b") (And (Unit "c") None))),"")------ λ> consumer (zeroOrMore (char 'k') <> string "abc") "kkkabc"--- (Right "kkkabc","")------ λ> consumer (zeroOrMore (char 'k') <> string "abc") "kkkabq"--- (Left (Unit "c"),"")------ λ> consumer (zeroOrMore (char 'k') <> string "abc") "kkkab"--- (Left (Unit "a character"),"")  module Descriptive.Char where 
src/Descriptive/Form.hs view
@@ -3,7 +3,14 @@  -- | Validating form with named inputs. -module Descriptive.Form where+module Descriptive.Form+  (-- * Combinators+   input+  ,validate+  -- * Description+  ,Form (..)+  )+  where  import           Descriptive @@ -18,7 +25,7 @@   | Constraint !Text   deriving (Show) --- | Consume any character.+-- | Consume any input value. input :: Text -> Consumer (Map Text Text) Form Text input name =   consumer (d,)@@ -30,9 +37,9 @@   where d = Unit (Input name)  -- | Validate a form input with a description of what's required.-validate :: Text-         -> (a -> Maybe b)-         -> Consumer (Map Text Text) Form a+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 (\s d -> redescribe (d s))
src/Descriptive/Formlet.hs view
@@ -3,7 +3,13 @@  -- | Validating indexed formlet with auto-generated input names. -module Descriptive.Formlet where+module Descriptive.Formlet+  (-- * Combinators+   indexed+  ,FormletState(..)+  -- * Description+  ,Formlet(..))+  where  import           Descriptive @@ -11,11 +17,13 @@ import qualified Data.Map.Strict as M import           Data.Text (Text) +-- | Description of a formlet. data Formlet   = Index !Integer   | Constrained !Text   deriving (Show) +-- | State used when running a formlet. data FormletState =   FormletState {formletMap :: (Map Integer Text)                ,formletIndex :: !Integer}
src/Descriptive/JSON.hs view
@@ -7,7 +7,16 @@  -- | A JSON API which describes itself. -module Descriptive.JSON where+module Descriptive.JSON+  (-- * Combinators+   obj+  ,key+  ,string+  ,integer+  -- * Description+  ,Doc(..)+  )+  where  import Data.Bifunctor import Data.Monoid@@ -26,7 +35,9 @@   deriving (Show)  -- | Consume an object.-obj :: Text -> Consumer Object Doc a -> Consumer Value Doc a+obj :: Text -- ^ Description of what the object is.+    -> Consumer Object Doc a -- ^ An object consumer.+    -> Consumer Value Doc a obj desc =   wrap (\v d -> (Wrap doc (fst (d mempty)),v))        (\v _ p ->@@ -40,7 +51,9 @@   where doc = Struct desc  -- | Consume from object at the given key.-key :: Text -> Consumer Value Doc a -> Consumer Object Doc a+key :: Text -- ^ The key to lookup.+    -> Consumer Value Doc a -- ^ A value consumer of the object at the key.+    -> Consumer Object Doc a key k =   wrap (\o d ->           first (Wrap doc)@@ -57,7 +70,8 @@   where doc = Key k  -- | Consume a string.-string :: Text -> Consumer Value Doc Text+string :: Text -- ^ Description of what the string is for.+       -> Consumer Value Doc Text string doc =   consumer (d,)            (\s ->@@ -67,7 +81,8 @@   where d = Unit (Text doc)  -- | Consume an integer.-integer :: Text -> Consumer Value Doc Integer+integer :: Text -- ^ Description of what the integer is for.+        -> Consumer Value Doc Integer integer doc =   consumer (d,)            (\s ->
src/Descriptive/Options.hs view
@@ -5,7 +5,18 @@  -- | Command-line options parser. -module Descriptive.Options where+module Descriptive.Options+  (-- * Combinators+   anyString+  ,constant+  ,flag+  ,prefix+  ,arg+  -- * Description+  ,Option(..)+  ,textDescription+  ,textOpt)+  where  import           Descriptive @@ -24,40 +35,6 @@   | Prefix !Text !Text   deriving (Show) --- | Make a text description of the command line options.-textDescription :: Description Option -> Text-textDescription = go . clean-  where clean (And None a) = clean a-        clean (And a None) = clean a-        clean (Or a None) = clean a-        clean (Or None a) = clean a-        clean (And a b) = And (clean a) (clean b)-        clean (Or a b) = Or (clean a) (clean b)-        clean a = a-        go d =-          case d of-            Unit o -> textOpt o-            Bounded min' _ d' ->-              "[" <> go d' <> "]" <>-              if min' == 0-                 then "*"-                 else "+"-            And a b -> go a <> " " <> go b-            Or a b -> "(" <> go a <> "|" <> go b <> ")"-            Sequence xs ->-              T.intercalate " "-                            (map go xs)-            Wrap o d' -> textOpt o <> " " <> go d'-            None -> ""---- | Make a text description of an option.-textOpt :: Option -> Text-textOpt (AnyString t) = T.map toUpper t-textOpt (Constant t) = t-textOpt (Flag t _) = "-f" <> t-textOpt (Arg t _) = "-" <> t <> " <...>"-textOpt (Prefix t _) = "-" <> t <> "<...>"- -- | Consume one argument from the argument list. anyString :: Text -> Consumer [Text] Option Text anyString help =@@ -113,3 +90,37 @@                          (Right text                          ,map snd (filter (\(j,_) -> j /= i && j /= i + 1) indexedArgs)))   where d = Unit (Arg name help)++-- | Make a text description of the command line options.+textDescription :: Description Option -> Text+textDescription = go . clean+  where clean (And None a) = clean a+        clean (And a None) = clean a+        clean (Or a None) = clean a+        clean (Or None a) = clean a+        clean (And a b) = And (clean a) (clean b)+        clean (Or a b) = Or (clean a) (clean b)+        clean a = a+        go d =+          case d of+            Unit o -> textOpt o+            Bounded min' _ d' ->+              "[" <> go d' <> "]" <>+              if min' == 0+                 then "*"+                 else "+"+            And a b -> go a <> " " <> go b+            Or a b -> "(" <> go a <> "|" <> go b <> ")"+            Sequence xs ->+              T.intercalate " "+                            (map go xs)+            Wrap o d' -> textOpt o <> " " <> go d'+            None -> ""++-- | Make a text description of an option.+textOpt :: Option -> Text+textOpt (AnyString t) = T.map toUpper t+textOpt (Constant t) = t+textOpt (Flag t _) = "-f" <> t+textOpt (Arg t _) = "-" <> t <> " <...>"+textOpt (Prefix t _) = "-" <> t <> "<...>"