-- 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.3.1.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: -- -- 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: -- --
    --
  1. The user input is unpacked into a String and then parsed. This can -- incur a performance hit for large inputs.
  2. --
  3. A Read-instance must be available for the expected type.
  4. --
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 take care of input and -- parameter-handling, and allow parameters to be supplied in the same -- line as the command's name (e.g. ":cmd param1 param2" on stdin). -- Provided parameters can be parsed and checked (say, against databases) -- before they are passed to the actual command function. They are -- relatively large units of abstraction, but they allow the easy -- creation of relatively sophisticated command loops, and have the -- advantage that one doesn't need to fiddle around with input handling -- in the middle of the actual command code. module System.REPL.Command -- | A REPL command, possibly with parameters. data Command m a Command :: Text -> (Text -> Bool) -> Text -> Maybe Int -> (Text -> m a) -> Command m a -- | The short name of the command. Purely informative. commandName :: Command m a -> Text -- | Returns whether a string matches a command name. The simplest form is -- s== for some string s, but more liberal matchings are -- possible. commandTest :: Command m a -> Text -> Bool -- | A description of the command. commandDesc :: Command m a -> Text -- | The number of parameters, if fixed. numParameters :: Command m a -> Maybe Int -- | Runs the command with the input text as parameter. runCommand :: Command m a -> Text -> m a -- | Prints information (the command name, description and, if given, the -- number of parameters) about a command to the console. commandInfo :: MonadIO m => Command m a -> m () -- | Takes a line of text and a command. If the text matches the given -- command's commandTest, the command is run with it. If not, -- Nothing is returned. runOnce :: MonadIO m => Text -> Command m a -> m (Maybe a) -- | Takes an input and tries to run it against a list of commands, trying -- the out in sequence. The first command whose commandTest -- returns True is executed. If none of the commands match, -- NothingFoundFailure is thrown. commandDispatch :: (MonadIO m, MonadCatch m, Functor m) => Text -> [Command m z] -> m z -- | Prints out a list of command names, with their descriptions. summarizeCommands :: MonadIO m => [Command m2 z] -> m () -- | Splits and trims the input of a command. 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). If the number of quotes in the input is not -- even, the operating will fail. -- -- Arguments are parsed using parsec's stringLiteral -- (haskell-style), meaning that escape sequences and unicode characters -- are handled automatically. readArgs :: Text -> Either Text [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 doesn't begin with a -- quote mark ("). readArgs and quoteArg are inverse up to -- suitable isomorphism, i.e. if 'readArgs orig = (Right res)', then it -- holds that readArgs orig = readArgs $ intercalate " " $ map -- quoteArg res quoteArg :: Text -> Text -- | Creates a command without parameters. makeCommand :: (MonadIO m, MonadCatch m, Functor m) => Text -> (Text -> Bool) -> Text -> (Text -> m a) -> Command m a -- | Creates a command with one parameter. makeCommand1 :: (MonadIO m, MonadCatch m, Functor m, Read a) => Text -> (Text -> Bool) -> Text -> Asker m a -> (Text -> a -> m z) -> Command m z -- | Creates a command with two parameters. makeCommand2 :: (MonadIO m, MonadCatch m, Functor m, Read a, Read b) => Text -> (Text -> Bool) -> Text -> Asker m a -> Asker m b -> (Text -> a -> b -> m z) -> Command m z -- | Creates a command with three parameters. makeCommand3 :: (MonadIO m, MonadCatch m, Functor m, Read a, Read b, Read c) => Text -> (Text -> Bool) -> Text -> Asker m a -> Asker m b -> Asker m c -> (Text -> a -> b -> c -> m z) -> Command m z -- | Creates a command with four parameters. makeCommand4 :: (MonadIO m, MonadCatch m, Functor m, Read a, Read b, Read c, Read d) => Text -> (Text -> Bool) -> Text -> Asker m a -> Asker m b -> Asker m c -> Asker m d -> (Text -> a -> b -> c -> d -> m z) -> Command m z -- | Creates a command with five parameters. makeCommand5 :: (MonadIO m, MonadCatch m, Functor m, Read a, Read b, Read c, Read d, Read e) => Text -> (Text -> Bool) -> Text -> 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 z -- | Creates a command with four parameters. makeCommand6 :: (MonadIO m, MonadCatch m, Functor m, Read a, Read b, Read c, Read d, Read e, Read f) => Text -> (Text -> Bool) -> Text -> 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 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, Read a) => Text -> (Text -> Bool) -> Text -> [Asker m a] -> [Asker m a] -> (Text -> [a] -> m z) -> Command m z instance Typeable ParamNumError instance Enum ParamNumError instance Show ParamNumError instance Eq ParamNumError instance Read ParamNumError instance Ord ParamNumError instance Exception ParamNumError instance Functor m => Functor (Command m)