-
Notifications
You must be signed in to change notification settings - Fork 0
/
Parser.hs
86 lines (73 loc) · 2.63 KB
/
Parser.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
module Parser (
defaultAppState,
AppState(..),
parseString
)
where
import Text.Parsec
import Text.Parsec.String
import Data.Functor.Identity (runIdentity)
data AppState = AppState {
appId :: Int,
universe :: Int,
name :: String,
stateFlags :: Int,
installDir :: String,
lastUpdated :: Int,
updateResult :: Int,
sizeOnDisk :: Int,
buildId :: Int,
lastOwner :: Int,
bytesToDownload :: Int,
bytesDownloaded :: Int,
autoUpdateBehavior :: Int,
allowOtherDownloadsWhileRunning :: Int,
userConfig :: UserConfig,
mountedDepots :: MountedDepots
} deriving (Eq, Show)
data UserConfig = UserConfig {language :: String} deriving (Eq, Show)
data MountedDepots = MountedDepots [MountedDepot] deriving (Eq, Show)
type MountedDepot = (Int,Int)
type AppParser = Parsec String AppState
type StateModifier k = k -> AppState -> AppState
defaultAppState = AppState 0 0 "" 0 "" 0 0 0 0 0 0 0 0 0 (UserConfig "") (MountedDepots [])
stringStateModifiers :: [(String, StateModifier String)]
stringStateModifiers = [("name", (\x u -> u {name = x})),
("installdir",(\x u -> u {installDir = x}))
]
intStateModifiers :: [(String,StateModifier Int)]
intStateModifiers = [ ("appid", (\x u -> u {appId = x})),
("Universe",(\x u -> u {universe = x})),
("StateFlags",(\x u -> u {stateFlags = x})),
("LastUpdated",(\x u -> u {lastUpdated = x})),
("UpdateResult",(\x u -> u {updateResult = x})),
("SizeOnDisk",(\x u -> u {sizeOnDisk = x})),
("buildid",(\x u -> u {buildId = x})),
("LastOwner",(\x u -> u {lastOwner = x})),
("BytesToDownload",(\x u -> u {bytesToDownload = x})),
("BytesDownloaded",(\x u -> u {bytesDownloaded = x})),
("AutoUpdateBehavior",(\x u -> u {autoUpdateBehavior = x})),
("AllowOtherDownloadsWhileRunning",(\x u -> u {allowOtherDownloadsWhileRunning = x}))
]
quotation = char '"'
quotedWord :: AppParser String
quotedWord = many $ satisfy (/='"')
parseQuote :: AppParser a -> AppParser a
parseQuote u = between quotation quotation u
parseLine :: AppParser ()
parseLine = do
label <- phrase
value <- phrase
modifyState $ case lookup label stringStateModifiers of
Just f -> f value
Nothing -> case lookup label intStateModifiers of
Just f -> f (read value :: Int)
Nothing -> id
where phrase = spaces >> parseQuote quotedWord
parseLoop :: AppParser ()
parseLoop = (try parseLine) <|> nextLine
where nextLine = manyTill anyToken newline >> return ()
parseBlock :: AppParser AppState
parseBlock = manyTill parseLoop eof >> getState
parseString :: AppState -> String -> (Either ParseError AppState)
parseString u = runIdentity . runParserT parseBlock u "parsing steam app string"