    -- | This module provides a simple parser for parsing input event
    -- control sequences.
    module Graphics.Vty.Input.Classify.Parse
      ( Parser
      , runParser
      , failParse
      , readInt
      , readChar
      , expectChar
      )
    where

    import Graphics.Vty.Input.Events
    import Graphics.Vty.Input.Classify.Types

    import Control.Monad.Trans.Maybe
    import Control.Monad.State

    type Parser a = MaybeT (State String) a

    -- | Run a parser on a given input string. If the parser fails, return
    -- 'Invalid'. Otherwise return the valid event ('Valid') and the
    -- remaining unparsed characters.
    runParser :: String -> Parser Event -> KClass
    runParser :: String -> Parser Event -> KClass
    runParser s :: String
    s parser :: Parser Event
    parser =
        case State String (Maybe Event) -> String -> (Maybe Event, String)
    forall s a. State s a -> s -> (a, s)
    runState (Parser Event -> State String (Maybe Event)
    forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
    runMaybeT Parser Event
    parser) String
    s of
            (Nothing, _)        -> KClass
    Invalid
            (Just e :: Event
    e, remaining :: String
    remaining) -> Event -> String -> KClass
    Valid Event
    e String
    remaining

    -- | Fail a parsing operation.
    failParse :: Parser a
    failParse :: Parser a
    failParse = String -> Parser a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail "invalid parse"

    -- | Read an integer from the input stream. If an integer cannot be
    -- read, fail parsing. E.g. calling readInt on an input of "123abc" will
    -- return '123' and consume those characters.
    readInt :: Parser Int
    readInt :: Parser Int
    readInt = do
        String
    s <- MaybeT (State String) String
    forall s (m :: * -> *). MonadState s m => m s
    get
        case (ReadS Int
    forall a. Read a => ReadS a
    reads :: ReadS Int) String
    s of
            [(i :: Int
    i, rest :: String
    rest)] -> String -> MaybeT (State String) ()
    forall s (m :: * -> *). MonadState s m => s -> m ()
    put String
    rest MaybeT (State String) () -> Parser Int -> Parser Int
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Int -> Parser Int
    forall (m :: * -> *) a. Monad m => a -> m a
    return Int
    i
            _ -> Parser Int
    forall a. Parser a
    failParse

    -- | Read a character from the input stream. If one cannot be read (e.g.
    -- we are out of characters), fail parsing.
    readChar :: Parser Char
    readChar :: Parser Char
    readChar = do
        String
    s <- MaybeT (State String) String
    forall s (m :: * -> *). MonadState s m => m s
    get
        case String
    s of
            c :: Char
    c:rest :: String
    rest -> String -> MaybeT (State String) ()
    forall s (m :: * -> *). MonadState s m => s -> m ()
    put String
    rest MaybeT (State String) () -> Parser Char -> Parser Char
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Char -> Parser Char
    forall (m :: * -> *) a. Monad m => a -> m a
    return Char
    c
            _ -> Parser Char
    forall a. Parser a
    failParse

    -- | Read a character from the input stream and fail parsing if it is
    -- not the specified character.
    expectChar :: Char -> Parser ()
    expectChar :: Char -> MaybeT (State String) ()
    expectChar c :: Char
    c = do
        Char
    c' <- Parser Char
    readChar
        if Char
    c' Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    c then () -> MaybeT (State String) ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return () else MaybeT (State String) ()
    forall a. Parser a
    failParse