-- | ParseCmd.hs -- A module which parse command from user and return parsed structure. module ParseCmd ( Parsed(..), POSTData, parseCmd ) where import ApplicativeParsec -- | Command parsed structure. data Parsed = NewPost POSTData | NewThread POSTData | DelPost POSTData | Help | Info | Unknown String deriving Show type POSTData = [(String, String)] -- | Parse command with parsec. parseCmd :: String -> Parsed parseCmd cmd = case parse parseCmd' "command" cmd of Left err -> Unknown (show err) Right p -> p -- Simple parsers. parseCmd' = (spaces0 *> cmd) <* (spaces0 *> eof) cmd = post <|> thread <|> del <|> (Help <$ string "help") <|> (Info <$ string "info") "right command" post = toResult <$> (string ">>" *> many1 digit) <*> sage <*> imgURL <*> body where toResult num sage u body = NewPost $ sage++u++[("replyto", num), ("body", body)] sage = [("sage", "1")] <$ (string "SAGE") <|> return [] thread = toResult <$> (char '*' *> many1 (oneOf $ ['A'..'Z']++['a'..'z'])) <*> imgURL <*> body where toResult tag u body = NewThread $ u++[("tag", tag), ("body", body)] imgURL = spaces0 *> (imgURL' <|> return []) imgURL' = (\u -> [("imgurl", "http://"++u)]) <$> (string "http://" *> many1 (alphaNum <|> oneOf "_-/.%?@") <* spaces0) body = char '\n' *> many1 anyChar del = liftA2 toResult (string "del" *> spaces1 *> many1 digit) (spaces1 *> many1 alphaNum) where toResult num pwd = DelPost [("number", num), ("password", pwd)] spaces0 = many (char ' ') spaces1 = many1 (char ' ')