packages feed

structured-cli 2.3.0.0 → 2.4.0.0

raw patch · 3 files changed

+48/−43 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- System.Console.StructuredCLI: instance GHC.Base.Monad m => Data.Default.Class.Default (System.Console.StructuredCLI.Parser m)
- System.Console.StructuredCLI: instance GHC.Base.Monad m => Data.Default.Class.Default (System.Console.StructuredCLI.Validator m)
- System.Console.StructuredCLI: instance GHC.Show.Show System.Console.StructuredCLI.ParseResult
+ System.Console.StructuredCLI: instance GHC.Base.Monad m => Data.Default.Class.Default (System.Console.StructuredCLI.Parser m GHC.Base.String)
+ System.Console.StructuredCLI: instance GHC.Base.Monad m => Data.Default.Class.Default (System.Console.StructuredCLI.Validator m GHC.Base.String)
+ System.Console.StructuredCLI: instance GHC.Show.Show a => GHC.Show.Show (System.Console.StructuredCLI.ParseResult a)
- System.Console.StructuredCLI: Done :: String -> String -> String -> ParseResult
+ System.Console.StructuredCLI: Done :: a -> String -> String -> ParseResult a
- System.Console.StructuredCLI: Fail :: String -> String -> ParseResult
+ System.Console.StructuredCLI: Fail :: String -> String -> ParseResult a
- System.Console.StructuredCLI: NoMatch :: ParseResult
+ System.Console.StructuredCLI: NoMatch :: ParseResult a
- System.Console.StructuredCLI: Partial :: [(String, String)] -> String -> ParseResult
+ System.Console.StructuredCLI: Partial :: [(String, String)] -> String -> ParseResult a
- System.Console.StructuredCLI: [getDoneMatched] :: ParseResult -> String
+ System.Console.StructuredCLI: [getDoneMatched] :: ParseResult a -> String
- System.Console.StructuredCLI: [getDoneRemaining] :: ParseResult -> String
+ System.Console.StructuredCLI: [getDoneRemaining] :: ParseResult a -> String
- System.Console.StructuredCLI: [getFailMessage] :: ParseResult -> String
+ System.Console.StructuredCLI: [getFailMessage] :: ParseResult a -> String
- System.Console.StructuredCLI: [getFailRemaining] :: ParseResult -> String
+ System.Console.StructuredCLI: [getFailRemaining] :: ParseResult a -> String
- System.Console.StructuredCLI: [getOutput] :: ParseResult -> String
+ System.Console.StructuredCLI: [getOutput] :: ParseResult a -> a
- System.Console.StructuredCLI: [getPartialHints] :: ParseResult -> [(String, String)]
+ System.Console.StructuredCLI: [getPartialHints] :: ParseResult a -> [(String, String)]
- System.Console.StructuredCLI: [getPartialRemaining] :: ParseResult -> String
+ System.Console.StructuredCLI: [getPartialRemaining] :: ParseResult a -> String
- System.Console.StructuredCLI: custom :: Monad m => String -> String -> Parser m -> m Bool -> Handler m -> CommandsT m ()
+ System.Console.StructuredCLI: custom :: Monad m => String -> String -> Parser m a -> m Bool -> Handler m a -> CommandsT m ()
- System.Console.StructuredCLI: data ParseResult
+ System.Console.StructuredCLI: data ParseResult a
- System.Console.StructuredCLI: labelParser :: Monad m => Node m -> String -> m ParseResult
+ System.Console.StructuredCLI: labelParser :: Monad m => Node m -> String -> m (ParseResult String)
- System.Console.StructuredCLI: param :: Monad m => String -> String -> Validator m -> Handler m -> CommandsT m ()
+ System.Console.StructuredCLI: param :: Monad m => String -> String -> Validator m a -> Handler m a -> CommandsT m ()
- System.Console.StructuredCLI: param' :: Monad m => String -> String -> Validator m -> m Bool -> Handler m -> CommandsT m ()
+ System.Console.StructuredCLI: param' :: Monad m => String -> String -> Validator m a -> m Bool -> Handler m a -> CommandsT m ()
- System.Console.StructuredCLI: type Handler m = String -> m Action
+ System.Console.StructuredCLI: type Handler m a = a -> m Action
- System.Console.StructuredCLI: type Parser m = Node m -> String -> m ParseResult
+ System.Console.StructuredCLI: type Parser m a = Node m -> String -> m (ParseResult a)
- System.Console.StructuredCLI: type Validator m = String -> m (Maybe String)
+ System.Console.StructuredCLI: type Validator m a = String -> m (Maybe a)

Files

example/Main.hs view
@@ -33,10 +33,9 @@ bar = param "bar" "<number of bars>" parseBars setBars >+ do         basic         frob-            where setBars str = do-                    let b = read str+            where setBars int = do                     bars <- gets bars-                    modify $ \s -> s { bars = bars + b }+                    modify $ \s -> s { bars = bars + int }                     return NewLevel  baz :: CommandsT StateM ()@@ -55,8 +54,8 @@          liftIO . putStrLn $ "frobbing " ++ show n ++ " bars"          return NoAction -parseBars :: Validator StateM-parseBars = return . fmap show . (readMaybe :: String -> Maybe Int)+parseBars :: Validator StateM Int+parseBars = return . readMaybe  main :: IO () main = do
src/System/Console/StructuredCLI.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE CPP,              ImplicitParams,+             ExistentialQuantification,              FlexibleContexts,              FlexibleInstances,              RecordWildCards,@@ -132,7 +133,7 @@  type StateM m = StateT (State m) m -type Handler m  = String -> m Action+type Handler m a = a -> m Action  -- | An 'Action' is returned as the result of a command handler provided by the user and -- it instructs the CLI of any changes in the CLI state@@ -150,28 +151,29 @@ -- | The 'Node' type contains the internal representation of a command. Normally there is no -- need to be concerned with it other than perhaps passing it opaquely to any utility parsers -- (like 'labelParser' for example), when writing a custom parser-data Node m = Node { getLabel    :: String,-                     getHint     :: String,-                     getBranches :: [Node m],-                     runParser   :: Parser m,-                     isEnabled   :: m Bool,-                     handle      :: Handler m }+data Node m = forall a . Node {+                        getLabel    :: String,+                        getHint     :: String,+                        getBranches :: [Node m],+                        runParser   :: Parser m a,+                        isEnabled   :: m Bool,+                        handle      :: Handler m a } -type Parser m = Node m -> String -> m ParseResult+type Parser m a = Node m -> String -> m (ParseResult a)  -- | A 'Validator' is a function to which a parsed string is given in order to perform -- any checks for validity that may be applicable, or even transforming the argument if -- necessary. Note that the validator runs in the "user" monad-type Validator m = String -> m (Maybe String)+type Validator m a = String -> m (Maybe a)  type ExceptionHandler m = CLIException -> m (Either CLIException ())  -- | There is no need to concern oneself with the 'ParseResult' type unless one is writing -- a custom parser, which should actually be rarer than not.-data ParseResult =+data ParseResult a =     Done {       -- | Output string to be fed to the command action handler-      getOutput :: String,+      getOutput :: a,       -- | Part of the string matched during parsing of a command       getDoneMatched :: String,       -- | Remaining input data@@ -264,11 +266,11 @@ instance (MonadIO m) => Default (Settings m) where     def = Settings Nothing "" (return " > ") False defExceptionHandler -instance (Monad m) => Default (Parser m) where+instance (Monad m) => Default (Parser m String) where     def = labelParser -instance (Monad m) => Default (Validator m) where-    def = return . pure . id+instance (Monad m) => Default (Validator m String) where+    def = return . pure  type ParserT m = ExceptT CLIException (HL.InputT (StateM m)) @@ -285,7 +287,7 @@ execCommandsT  = fmap snd . runCommandsT  data SearchResult m = Completed { completedNode      :: Node m,-                                  completedOutput    :: String,+                                  completedAction    :: m Action,                                   completedMatched   :: String,                                   completedRemaining :: String }                     | Incomplete { incompleteNode    :: Node m,@@ -361,10 +363,10 @@ -- | Build a command node that takes one parameter (delimited by space). The parsed parameter -- is fed to the validator monadic function (in the "user" monad) and the resulting string -- if any is fed in turn as an argument to the handler action (also in the "user" monad).-param :: (Monad m) => String       -- ^ Command keyword-                   -> String       -- ^ Help text for this command (including argument description)-                   -> Validator m  -- ^ Monadic validator (in the "user" monad)-                   -> Handler m    -- ^ Handling action. Takes the validator output as argument+param :: (Monad m) => String         -- ^ Command keyword+                   -> String         -- ^ Help text for this command (including argument description)+                   -> Validator m a  -- ^ Monadic validator (in the "user" monad)+                   -> Handler m a    -- ^ Handling action. Takes the validator output as argument                    -> CommandsT m () param label hint validator handler =     param' label hint validator (return True) handler@@ -372,22 +374,22 @@ -- | A variation of 'param' that allows for "disabling" the command at runtime by -- running the given "enable" monadic action (as always in the "user" monad) to check -- if the command should be displayed as an option and/or accepted or not.-param' :: (Monad m) => String       -- ^ Command keyword-                    -> String       -- ^ Help text for this command (including argument description)-                    -> Validator m  -- ^ Monadic validator (in the "user" monad)-                    -> m Bool       -- ^ Enable action in the "user" monad-                    -> Handler m    -- ^ Handling action. Takes the validator output as argument+param' :: (Monad m) => String         -- ^ Command keyword+                    -> String         -- ^ Help text for this command (including argument description)+                    -> Validator m a  -- ^ Monadic validator (in the "user" monad)+                    -> m Bool         -- ^ Enable action in the "user" monad+                    -> Handler m a    -- ^ Handling action. Takes the validator output as argument                     -> CommandsT m () param' label hint validator enable handler = do   custom label hint parser enable handler          where parser = paramParser hint validator  -- | Create a command using a custom parser, providing thus complete flexibility-custom :: (Monad m) => String     -- ^ Command keyword-                    -> String     -- ^ Help text for this command-                    -> Parser m   -- ^ Custom parser (runs in the "user" monad)-                    -> m Bool     -- ^ Enable action in the "user" monad-                    -> Handler m  -- ^ Handling action. Takes the validator output as argument+custom :: (Monad m) => String      -- ^ Command keyword+                    -> String      -- ^ Help text for this command+                    -> Parser m a  -- ^ Custom parser (runs in the "user" monad)+                    -> m Bool      -- ^ Enable action in the "user" monad+                    -> Handler m a -- ^ Handling action. Takes the validator output as argument                     -> CommandsT m () custom label hint parser enable handler = do   let node = Node { getLabel    = label,@@ -416,7 +418,7 @@  -- | A utility parser that reads an input and parses a command label. It can be used as part of -- custom parsers to first read the command keyword before parsing any arguments etc.-labelParser :: (Monad m) => Node m -> String -> m ParseResult+labelParser :: (Monad m) => Node m -> String -> m (ParseResult String) labelParser Node{..} input = do     case nextWord input of       ("?", remaining) ->@@ -432,7 +434,7 @@ (-.-) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c (-.-) = (.).(.) -paramParser :: (Monad m) => String -> (String -> m (Maybe String)) -> Node m -> String -> m ParseResult+paramParser :: Monad m => String -> (String -> m (Maybe a)) -> Node m -> String -> m (ParseResult a) paramParser hint validator = parseParam -.- labelParser     where parseParam  = flip (>>=) parseParam'           parseParam' (Done _ matched rest) =@@ -444,8 +446,11 @@                 (word, remaining) -> do                   v <- validator word                   return $ maybe (badArg rest) (\x -> Done x (matched ++ ' ':word) remaining) v-          parseParam' result =-              return result+          parseParam' (Fail x y) =+              return $ Fail x y+          parseParam' (Partial x y) =+              return $ Partial x y+          parseParam' NoMatch = return NoMatch           badArg = Fail hint  nextWord :: String -> (String, String)@@ -520,9 +525,10 @@     _ ->       return () -    where buildPrompt ns = intercalate " " . (: reverse ns) <$> getPrompt ?settings+    where buildPrompt ns = (showStack ns ++) <$> getPrompt ?settings           withLabels     = fmap fst <$> getStack           restore stack  = liftStateM . modify $ \s -> s { stack = stack }+          showStack      = intercalate " " . reverse  getStack :: (Monad m) => ParserT m [Level m] getStack = liftStateM $ gets stack@@ -565,7 +571,7 @@   case result of     [Completed{ completedNode=node@Node{..}, ..}] -> do       push completedMatched node-      action <- liftUserM $ handle completedOutput+      action <- liftUserM completedAction       process' completedRemaining node action     _ ->       if checkForHelp . dropWhile isSpace $ reverse input then do@@ -621,11 +627,11 @@               enabled <- lift isEnabled               if enabled then do                   result <- lift $ runParser node input-                  debugM $ "ran " ++ getLabel ++ " parser on " ++ show input ++ ": " ++ show result+                  debugM $ "ran " ++ getLabel ++ " parser on " ++ show input ++ ": "  -- ++ show result                   case result of                     Done output matched rest ->                         return Completed { completedNode      = node,-                                           completedOutput    = output,+                                           completedAction    = handle output,                                            completedMatched   = matched,                                            completedRemaining = rest }                     Fail msg rest ->
structured-cli.cabal view
@@ -1,5 +1,5 @@ name:                structured-cli-version:             2.3.0.0+version:             2.4.0.0 synopsis:            Application library for building interactive console CLIs description:         This module provides the tools to build a complete "structured" CLI application, similar to those found in systems like Cisco IOS or console configuration utilities etc. It aims to be easy for implementors to use. homepage:            https://gitlab.com/codemonkeylabs/structured-cli#readme