-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Toolkit for quickly whipping up config files and command-line interfaces.
--
@package repl-toolkit
@version 0.4.0.0
-- | Contains logic for reading configuration files.
module System.REPL.Config
-- | Tries to read a configuration from file. If the file is missing, a
-- default instance is written to file and returned. The following
-- exceptions may be thrown:
--
--
-- - IOException, if the IO operations associated with reading
-- or creating the configuration file fail, and
-- - An exception of type e if the configuration file is
-- present, but its contents can't be parsed.
--
readConfigFile :: (MonadThrow m, Functor m, MonadIO m, Default a, Exception e) => FilePath -> (ByteString -> Either e a) -> (a -> ByteString) -> m a
-- | Variant of readConfigFile that uses JSON for (de)serialization.
--
-- If the file's content's can't be parsed, a NoParseError will be
-- thrown.
readConfigJSON :: (MonadThrow m, Functor m, MonadIO m, Default a, ToJSON a, FromJSON a) => FilePath -> m a
-- | Variant of readConfigFile that uses Show and Read
-- for (de)serialization.
--
-- If the file's content's can't be parsed, a NoParseError will be
-- thrown.
readConfigShow :: (MonadThrow m, Functor m, MonadIO m, Default a, Show a, Read a) => FilePath -> m a
-- | Indicates that some string was not able to be parsed.
data NoParseError
NoParseError :: Text -> NoParseError
instance Typeable NoParseError
instance Show NoParseError
instance Eq NoParseError
instance Read NoParseError
instance Exception NoParseError
-- | Helper functions relating to State.
module System.REPL.State
-- | Extracts a result from the current state. Defined as get1 f =
-- liftM f get.
get1 :: Monad m => (s -> a) -> StateT s m a
-- | Extracts two results from the current state.
get2 :: Monad m => (s -> a) -> (s -> b) -> StateT s m (a, b)
-- | Extracts three results from the current state.
get3 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> StateT s m (a, b, c)
-- | Extracts four results from the current state.
get4 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> (s -> d) -> StateT s m (a, b, c, d)
-- | Extracts five results from the current state.
get5 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> (s -> d) -> (s -> e) -> StateT s m (a, b, c, d, e)
-- | Extracts six results from the current state.
get6 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> (s -> d) -> (s -> e) -> (s -> f) -> StateT s m (a, b, c, d, e, f)
-- | Extracts seven results from the current state.
get7 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> (s -> d) -> (s -> e) -> (s -> f) -> (s -> g) -> StateT s m (a, b, c, d, e, f, g)
-- | Extracts eight results from the current state.
get8 :: Monad m => (s -> a) -> (s -> b) -> (s -> c) -> (s -> d) -> (s -> e) -> (s -> f) -> (s -> g) -> (s -> h) -> StateT s m (a, b, c, d, e, f, g, h)
-- | Functions to expedite the building of REPLs.
module System.REPL
-- | Prints a string to stderr.
putErr :: ListLikeIO full item => full -> IO ()
-- | Prints a string, followed by a newline character, to stderr.
putErrLn :: ListLikeIO full item => full -> IO ()
-- | Prints > and asks the user to input a line.
prompt :: (MonadIO m, ListLikeIO full item) => m full
-- | Prints its first argument and, in the same line, asks the user to
-- input a line.
prompt' :: (MonadIO m, ListLikeIO full item, ListLikeIO full' item') => full -> m full'
-- | The same as prompt, but aborts as soon as the user presses a given key
-- (commonly '\ESC'). This function temporarily tries to set the
-- buffering mode to NoBuffering via hSetBuffering, which may not
-- be supported. See the documentation of hSetBuffering for
-- details.
promptAbort :: (MonadIO m, ListLikeIO full item, ListLikeIO full' Char, MonadCatch m) => Char -> full -> m full'
-- | A prompt.
type PromptMsg = Text
-- | An error message indicating that a value wasn't able to be parsed.
type TypeErrorMsg = Text
-- | An error message indicating that a value failied a predicate.
type PredicateErrorMsg = Text
-- | A predicate which a value has to fulfil.
type Predicate m a = a -> m Bool
-- | A parser which either returns a parsed value or an error message.
type Parser a = Text -> Either Text a
-- | The description of an 'ask for user input'-action. The type parameters
-- are the used monad (typically IO or ExceptT), the type
-- of the read value and the type of the error that is thrown in case of
-- failures.
--
-- The components are a prompt, a parser, and a predicate that the parsed
-- value must fulfil. The predicate, being monadic, can perform
-- arbitrarily complex tests, such as checking whether a given date is in
-- the future, whether an item is in a database, whether a file with a
-- given name exists, etc.
data Asker m a
Asker :: Text -> Parser a -> (a -> m (Either Text ())) -> Asker m a
-- | The prompt to be displayed to the user.
askerPrompt :: Asker m a -> Text
-- | The parser for the input value.
askerParser :: Asker m a -> Parser a
-- | The predicate which the input, once read, must fulfill. The Left side
-- is an error message.
askerPredicate :: Asker m a -> a -> m (Either Text ())
-- | Represents a failure during the running of an asking function. Either
-- the input was incorrect in some way, or the process was aborted by the
-- user.
data AskFailure
-- | The input wasn't able to be parsed.
TypeFailure :: TypeErrorMsg -> AskFailure
-- | The parsed value failed a predicate.
PredicateFailure :: PredicateErrorMsg -> AskFailure
-- | An incorrect number of parameters was passed.
ParamFailure :: Text -> AskFailure
-- | No action was appropriate for the given input.
NothingFoundFailure :: AskFailure
-- | The input was aborted by the user.
AbortFailure :: AskFailure
-- | Creates a general Asker with a custom parsing function and a
-- predicate that the parsed value has to pass. If either the parsing or
-- the predicate fail, one of the given error messages is displayed.
askerP :: (Monad m, Functor m) => PromptMsg -> PredicateErrorMsg -> Parser a -> Predicate m a -> Asker m a
-- | Creates an Asker which only cares about the type of the input.
typeAskerP :: (Monad m, Functor m) => PromptMsg -> Parser a -> Asker m a
-- | An asker which asks for an optional value. If only whitespace is
-- entered (according to isSpace), it returns Nothing
-- without further parsing or checking; otherwise, it behaves identically
-- to asker.
maybeAskerP :: (Monad m, Functor m) => PromptMsg -> PredicateErrorMsg -> Parser a -> Predicate m a -> Asker m (Maybe a)
-- | A parser based on readMaybe. This suffices for the parsing of
-- most data types.
readParser :: Read a => TypeErrorMsg -> Text -> (Either Text a)
-- | Creates a general Asker with readMaybe as its parser.
-- Using readMaybe is perfectly fine for most values, but it has
-- two drawbacks:
--
--
-- - The user input is unpacked into a String and then parsed. This can
-- incur a performance hit for large inputs.
-- - A Read-instance must be available for the expected type.
--
asker :: (Monad m, Functor m, Read a) => PromptMsg -> TypeErrorMsg -> PredicateErrorMsg -> Predicate m a -> Asker m a
-- | Creates an Asker based on Read which just cares about the type
-- of the input.
typeAsker :: (Monad m, Functor m, Read a) => PromptMsg -> TypeErrorMsg -> Asker m a
-- | Creates an Asker which takes its input verbatim as Text.
-- The input thus only has to pass a predicate, not any parsing.
predAsker :: (Monad m, Functor m) => PromptMsg -> Text -> (Text -> m Bool) -> Asker m Verbatim
-- | An asker based on Read which asks for an optional value.
maybeAsker :: (Monad m, Functor m, Read a) => PromptMsg -> TypeErrorMsg -> PredicateErrorMsg -> Predicate m a -> Asker m (Maybe a)
-- | A verbatim Text whose Read instance simply returns the read string,
-- as-is. This is useful for askers which ask for strings without quotes.
newtype Verbatim
Verbatim :: Text -> Verbatim
fromVerbatim :: Verbatim -> Text
-- | Executes an Asker. If the process fails, an exception is thrown.
ask :: (MonadIO m, MonadCatch m, Functor m) => Asker m a -> Maybe Text -> m a
-- | See ask. Always reads the input from stdin.
--
--
-- ask' a = ask a Nothing
--
ask' :: (MonadIO m, MonadCatch m, Functor m) => Asker m a -> m a
-- | Executes an Asker. If the Text argument is Nothing, the user is
-- asked to enter a line on stdin. If it is Just x, x
-- is taken to be input.
askEither :: (MonadIO m, MonadCatch m, Functor m) => Asker m a -> Maybe Text -> m (Either AskFailure a)
-- | Repeatedly executes an ask action until the user enters a valid value.
-- Error messages are printed each time.
untilValid :: (MonadIO m, MonadCatch m, Functor m, Read a) => m a -> m a
instance Typeable AskFailure
instance Eq AskFailure
instance Read Verbatim
instance Show AskFailure
instance Exception AskFailure
-- | Provides Commands for REPLs. Commands are there to provide high-level
-- handling of user input and to offer functionality in a standard,
-- composable way.
--
-- Use cases:
--
--
-- - Asking the user for input that has to be of the right format or
-- fulfil specific constraints, such as asking for an Int
-- between 0 and 10, or asking for a username that has to exist in some
-- database.
-- - Creating command hierarchies, e.g.
--
--
--
-- >>> myVersionControl commit "my first commit" only-binaries
--
--
-- In this example, we could have commit as a root command that
-- consumes the commit name "my first commit" and hands over to the
-- sub-command only-binaries.
--
--
-- - Creating a REPL out of individual commands. Let us say that we
-- have a version control system with commit, revert, diff
-- commands, plus an exit command like "exit", and one that prints some
-- "command not recognized" message if the user's input doesn't match any
-- commands. We can compose these commands with makeREPL,
-- providing robust command selection and obviating the need for manually
-- writing the input handling loop.
--
--
-- Commands can take their input in one line, e.g.
--
--
-- >>> :cmd param1 "param2 with spaces" param3
--
--
-- or they can ask for missing parameters if so configured:
--
--
-- >>> :cmd param1 "param2 with spaces"
-- Please enter param3:
--
module System.REPL.Command
-- | A REPL command, possibly with parameters.
data Command m i a
Command :: Text -> (i -> Bool) -> Text -> ([i] -> m (a, [i])) -> Command m i a
-- | The short name of the command. Purely informative.
commandName :: Command m i a -> Text
-- | Returns whether the first part of an input (the command name) matches
-- a the command. The simplest form is ((==) . getPart) s for
-- some string s, but more liberal matchings are possible.
commandTest :: Command m i a -> i -> Bool
-- | A description of the command.
commandDesc :: Command m i a -> Text
-- | Runs the command with the input text as parameter, returning the
-- unconsumed input.
runPartialCommand :: Command m i a -> [i] -> m (a, [i])
-- | Runs the command with the input text as parameter, discarding any
-- left-over input.
runCommand :: (Functor m, Monad m, MonadThrow m) => Command m Text a -> Text -> m a
-- | Runs the command with the input text as parameter. If any input is
-- left unconsumed, an error is thrown.
runSingleCommand :: (MonadThrow m, Functor m) => Command m Text a -> Text -> m a
-- | Takes a list xs and executes the first command in a list
-- whose commandTest matches the input.
--
-- Note that the resultant command cs
-- runPartialCommand should only be executed with an input
-- t if 'commandTest c t' == True', where t' is either
-- head (readArgs t) or mempty if t is empty.
-- Otherwise, the result is undefined.
oneOf :: Monoid i => Text -> Text -> [Command m i a] -> Command m i a
-- | Adds a list of possible subcommands after a command (that should leave
-- some input unconsumed). Ignoring all the required parameters for a
-- moment,
--
--
-- subcommand x xs = x >>- oneOf xs
--
subcommand :: (Functor m, Monad m, Monoid i) => Command m i a -> [a -> Command m i b] -> Command m i b
-- | Runs a REPL based on a set of commands. For a line of input, the
-- commands are tried in following order:
--
--
-- - the "exit" command,
-- - all regular commands, and then
-- - the "unknown" command.
--
makeREPL :: (Functor m, MonadIO m, MonadCatch m, Functor f, Foldable f) => [Command m Text a] -> Command m Text b -> Command m Text c -> m Text -> f (Handler m ()) -> m ()
-- | Generic error related to command execution.
data SomeCommandError
SomeCommandError :: e -> SomeCommandError
-- | The input of a command was malformed and could not interpreted. I.e.
-- the input contained inadmissible characters, or quotes were
-- mismatched. The Text argument contains the parser error.
data MalformedParamsError
MalformedParamsError :: Text -> MalformedParamsError
-- | Too few parameters were given to a command. The first value is the
-- minium, the second the actual number.
data TooFewParamsError
TooFewParamsError :: Int -> Int -> TooFewParamsError
-- | Too many parameters were given to a command. The first value is the
-- maximum, the second the actual number.
data TooManyParamsError
TooManyParamsError :: Int -> Int -> TooManyParamsError
-- | Splits and trims the input of a command. If the input cannot be
-- parsed, a MalformedCommand exception is thrown.
--
--
--
-- Any non-whitespace sequence of characters is interpreted as one
-- argument, unless double quotes (") are used, in which case they
-- demarcate an argument. Each argument is parsed as a haskell string
-- literal (quote-less arguments have quotes inserted around them).
--
-- Arguments are parsed using parsec's stringLiteral
-- (haskell-style), meaning that escape sequences and unicode characters
-- are handled automatically.
readArgs :: MonadThrow m => Text -> m [Text]
-- | Gets the first part of a command string, or the empty string, if the
-- comand string is empty.
getName :: (Functor m, MonadThrow m) => Text -> m Text
-- | Surrounds an argument in quote marks, if necessary. This is useful
-- when arguments were extracted via readArgs, which deletes quote
-- marks. Quotes are placed around the input iff it is empty or contains
-- whitespace.
quoteArg :: Text -> Text
-- | Prints out a list of command names, with their descriptions.
summarizeCommands :: MonadIO m => [Command m2 i z] -> m ()
-- | Creates a command without parameters.
makeCommand :: (MonadIO m, MonadCatch m, Functor m, Monoid i) => Text -> (i -> Bool) -> Text -> (i -> m z) -> Command m i z
-- | Creates a command with one parameter.
makeCommand1 :: (MonadIO m, MonadCatch m, Functor m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a -> (Text -> a -> m z) -> Command m Text z
-- | Creates a command with two parameters.
makeCommand2 :: (MonadIO m, MonadCatch m, Functor m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a -> Asker m b -> (Text -> a -> b -> m z) -> Command m Text z
-- | Creates a command with three parameters.
makeCommand3 :: (MonadIO m, MonadCatch m, Functor m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a -> Asker m b -> Asker m c -> (Text -> a -> b -> c -> m z) -> Command m Text z
-- | Creates a command with four parameters.
makeCommand4 :: (MonadIO m, MonadCatch m, Functor m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a -> Asker m b -> Asker m c -> Asker m d -> (Text -> a -> b -> c -> d -> m z) -> Command m Text z
-- | Creates a command with five parameters.
makeCommand5 :: (MonadIO m, MonadCatch m, Functor m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a -> Asker m b -> Asker m c -> Asker m d -> Asker m e -> (Text -> a -> b -> c -> d -> e -> m z) -> Command m Text z
-- | Creates a command with six parameters.
makeCommand6 :: (MonadIO m, MonadCatch m, Functor m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a -> Asker m b -> Asker m c -> Asker m d -> Asker m e -> Asker m f -> (Text -> a -> b -> c -> d -> e -> f -> m z) -> Command m Text z
-- | Creates a command with seven parameters.
makeCommand7 :: (MonadIO m, MonadCatch m, Functor m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a -> Asker m b -> Asker m c -> Asker m d -> Asker m e -> Asker m f -> Asker m g -> (Text -> a -> b -> c -> d -> e -> f -> g -> m z) -> Command m Text z
-- | Creates a command with eight parameters.
makeCommand8 :: (MonadIO m, MonadCatch m, Functor m) => Text -> (Text -> Bool) -> Text -> Bool -> Asker m a -> Asker m b -> Asker m c -> Asker m d -> Asker m e -> Asker m f -> Asker m g -> Asker m h -> (Text -> a -> b -> c -> d -> e -> f -> g -> h -> m z) -> Command m Text z
-- | Creates a command with a list of parameters. The first list
-- necc of Askers indicates the necessary parameters; the
-- user must at least provide this many. The second list opt
-- contains Askers for additional, optional parameters, and may be
-- infinite. If the number of passed parameters exceeds length necc +
-- length opt, or if any Asker fails, the command returns an
-- AskFailure.
makeCommandN :: (MonadIO m, MonadCatch m, Functor m) => Text -> (Text -> Bool) -> Text -> Bool -> [Asker m a] -> [Asker m a] -> (Text -> [a] -> m z) -> Command m Text z
instance Typeable SomeCommandError
instance Typeable MalformedParamsError
instance Typeable TooManyParamsError
instance Typeable TooFewParamsError
instance Show MalformedParamsError
instance Eq MalformedParamsError
instance Ord MalformedParamsError
instance Show TooManyParamsError
instance Eq TooManyParamsError
instance Ord TooManyParamsError
instance Show TooFewParamsError
instance Eq TooFewParamsError
instance Ord TooFewParamsError
instance (Functor m, Monad m) => Bind (Command m i)
instance (Functor m, Monad m) => Apply (Command m i)
instance Functor m => Functor (Command m i)
instance Exception TooFewParamsError
instance Exception TooManyParamsError
instance Exception MalformedParamsError
instance Exception SomeCommandError
instance Show SomeCommandError