@@ -0,0 +1,57 @@
1+-- | This module provides a simple parser for parsing input event
2+-- control sequences.
3+module Graphics.Vty.Input.Classify.Parse
4+ ( Parser
5+ , runParser
6+ , failParse
7+ , readInt
8+ , readChar
9+ , expectChar
10+ ) where
11+
12+import Graphics.Vty.Input.Events
13+import Graphics.Vty.Input.Classify.Types
14+
15+import Control.Monad.Trans.Maybe
16+import Control.Monad.State
17+
18+type Parser a = MaybeT (State String) a
19+
20+-- | Run a parser on a given input string. If the parser fails, return
21+-- 'Invalid'. Otherwise return the valid event ('Valid') and the
22+-- remaining unparsed characters.
23+runParser :: String -> Parser Event -> KClass
24+runParser s parser =
25+ case runState (runMaybeT parser) s of
26+ (Nothing, _) -> Invalid
27+ (Just e, remaining) -> Valid e remaining
28+
29+-- | Fail a parsing operation.
30+failParse :: Parser a
31+failParse = fail "invalid parse"
32+
33+-- | Read an integer from the input stream. If an integer cannot be
34+-- read, fail parsing. E.g. calling readInt on an input of "123abc" will
35+-- return '123' and consume those characters.
36+readInt :: Parser Int
37+readInt = do
38+ s <- get
39+ case (reads :: ReadS Int) s of
40+ [(i, rest)] -> put rest >> return i
41+ _ -> failParse
42+
43+-- | Read a character from the input stream. If one cannot be read (e.g.
44+-- we are out of characters), fail parsing.
45+readChar :: Parser Char
46+readChar = do
47+ s <- get
48+ case s of
49+ c:rest -> put rest >> return c
50+ _ -> failParse
51+
52+-- | Read a character from the input stream and fail parsing if it is
53+-- not the specified character.
54+expectChar :: Char -> Parser ()
55+expectChar c = do
56+ c' <- readChar
57+ if c' == c then return () else failParse