|
|
@ -1,24 +1,47 @@ |
|
|
|
{-# LANGUAGE OverloadedStrings #-} |
|
|
|
module IRCParser where |
|
|
|
|
|
|
|
import Data.Text (strip) |
|
|
|
import Data.Text.Encoding (decodeUtf8) |
|
|
|
import Data.ByteString (pack) |
|
|
|
import Data.Attoparsec.ByteString |
|
|
|
import Control.Applicative |
|
|
|
import Data.Either.Combinators (rightToMaybe) |
|
|
|
import Types |
|
|
|
|
|
|
|
-- :nisstyre!wes@oftn/oswg-member/Nisstyre PRIVMSG #thisisatestwhatever :yay\r\n |
|
|
|
-- :nisstyre!wes@oftn/oswg-member/Nisstyre PART #thisisatestwhatever :\"WeeChat 2.2\"\r\n |
|
|
|
-- :nisstyre!wes@oftn/oswg-member/Nisstyre JOIN #thisisatestwhatever\r\n |
|
|
|
-- :nisstyre!wes@oftn/oswg-member/Nisstyre QUIT :Quit: WeeChat 2.2\r\n |
|
|
|
-- PING :asimov.freenode.net\r\n |
|
|
|
stripWhitespace = filter $ (all id) . (sequence $ map (/=) [" ", "\r", "\n", ""]) |
|
|
|
|
|
|
|
space = word8 32 |
|
|
|
notSpace = notWord8 32 |
|
|
|
colon = word8 58 -- : |
|
|
|
|
|
|
|
-- 13 = \r, 10 = \n |
|
|
|
crlf c = c == 13 || c == 10 |
|
|
|
|
|
|
|
-- : |
|
|
|
colon = word8 58 |
|
|
|
bang = (== 33) -- ! |
|
|
|
atsign = (== 64) -- @ |
|
|
|
isSpace = (== 32) |
|
|
|
|
|
|
|
parseNick = takeWhile1 (not . bang) |
|
|
|
|
|
|
|
parseUsername = do |
|
|
|
_ <- word8 33 |
|
|
|
username <- takeWhile1 (not . atsign) |
|
|
|
return username |
|
|
|
|
|
|
|
parseHostmask = do |
|
|
|
_ <- word8 64 |
|
|
|
hostmask <- takeWhile1 (not . isSpace) |
|
|
|
return hostmask |
|
|
|
|
|
|
|
parseSource = do |
|
|
|
nickname <- parseNick |
|
|
|
username <- parseUsername |
|
|
|
hostmask <- parseHostmask |
|
|
|
return $ Source |
|
|
|
(decodeUtf8 nickname) |
|
|
|
(decodeUtf8 username) |
|
|
|
(decodeUtf8 hostmask) |
|
|
|
|
|
|
|
command = choice $ map string ["PRIVMSG", "PART", "JOIN", "QUIT", "PING"] |
|
|
|
|
|
|
@ -33,7 +56,7 @@ parseArgs = do |
|
|
|
args <- (argument `sepBy` space) <|> alwaysMatch [] |
|
|
|
_ <- space <|> (alwaysMatch 0) |
|
|
|
finalArg <- parseFinalArg <|> (alwaysMatch "") |
|
|
|
return (args, finalArg) |
|
|
|
return $ args ++ [finalArg] |
|
|
|
|
|
|
|
source = do |
|
|
|
_ <- colon |
|
|
@ -49,6 +72,12 @@ parseMessage = do |
|
|
|
commandName <- command |
|
|
|
_ <- space |
|
|
|
arguments <- parseArgs |
|
|
|
return (pack sourceName, commandName, arguments) |
|
|
|
|
|
|
|
let source = parseOnly parseSource $ pack sourceName |
|
|
|
|
|
|
|
return $ Message |
|
|
|
(rightToMaybe source) |
|
|
|
(decodeUtf8 commandName) |
|
|
|
(map strip $ stripWhitespace $ map decodeUtf8 arguments) |
|
|
|
|
|
|
|
runParseMessage = parseOnly parseMessage |
|
|
|