aboutsummaryrefslogtreecommitdiffstats
path: root/src/Reaktor/IRC.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Reaktor/IRC.hs')
-rw-r--r--src/Reaktor/IRC.hs450
1 files changed, 450 insertions, 0 deletions
diff --git a/src/Reaktor/IRC.hs b/src/Reaktor/IRC.hs
new file mode 100644
index 0000000..325374d
--- /dev/null
+++ b/src/Reaktor/IRC.hs
@@ -0,0 +1,450 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Reaktor.IRC
+ ( Command(..)
+ ) where
+
+import Data.Aeson
+import Data.Aeson.Types (typeMismatch)
+import qualified Data.HashMap.Lazy as M
+import Data.Hashable (Hashable)
+import Data.String.Conversions
+import qualified Data.Text.Extended as T
+import qualified Data.Text.Read as T
+import GHC.Generics (Generic)
+import Prelude.Extended
+
+data Command =
+ UnknownCommand Text | UnknownReply Int
+ | ADMIN
+ | AWAY
+ | CONNECT
+ | DIE
+ | ERROR
+ | INFO
+ | INVITE
+ | ISON
+ | JOIN
+ | KICK
+ | KILL
+ | LINKS
+ | LIST
+ | LUSERS
+ | MODE
+ | MOTD
+ | NAMES
+ | NICK
+ | NJOIN
+ | NOTICE
+ | OPER
+ | PART
+ | PASS
+ | PING
+ | PONG
+ | PRIVMSG
+ | QUIT
+ | REHASH
+ | RESTART
+ | SERVER
+ | SERVICE
+ | SERVLIST
+ | SQUERY
+ | SQUIRT
+ | SQUIT
+ | STATS
+ | SUMMON
+ | TIME
+ | TOPIC
+ | TRACE
+ | USER
+ | USERHOST
+ | USERS
+ | VERSION
+ | WALLOPS
+ | WHO
+ | WHOIS
+ | WHOWAS
+
+ | RPL_WELCOME
+ | RPL_YOURHOST
+ | RPL_CREATED
+ | RPL_MYINFO
+ | RPL_BOUNCE
+
+ | RPL_TRACELINK
+ | RPL_TRACECONNECTING
+ | RPL_TRACEHANDSHAKE
+ | RPL_TRACEUNKNOWN
+ | RPL_TRACEOPERATOR
+ | RPL_TRACEUSER
+ | RPL_TRACESERVER
+ | RPL_TRACESERVICE
+ | RPL_TRACENEWTYPE
+ | RPL_TRACECLASS
+ | RPL_TRACERECONNECT
+ | RPL_STATSLINKINFO
+ | RPL_STATSCOMMANDS
+ | RPL_ENDOFSTATS
+ | RPL_UMODEIS
+ | RPL_SERVLIST
+ | RPL_SERVLISTEND
+ | RPL_STATSUPTIME
+ | RPL_STATSOLINE
+ | RPL_LUSERCLIENT
+ | RPL_LUSEROP
+ | RPL_LUSERUNKNOWN
+ | RPL_LUSERCHANNELS
+ | RPL_LUSERME
+ | RPL_ADMINME
+ | RPL_ADMINLOC1
+ | RPL_ADMINLOC2
+ | RPL_ADMINEMAIL
+ | RPL_TRACELOG
+ | RPL_TRACEEND
+ | RPL_TRYAGAIN
+ | RPL_AWAY
+ | RPL_USERHOST
+ | RPL_ISON
+ | RPL_UNAWAY
+ | RPL_NOWAWAY
+ | RPL_WHOISUSER
+ | RPL_WHOISSERVER
+ | RPL_WHOISOPERATOR
+ | RPL_WHOWASUSER
+ | RPL_ENDOFWHO
+ | RPL_WHOISIDLE
+ | RPL_ENDOFWHOIS
+ | RPL_WHOISCHANNELS
+ | RPL_LISTSTART
+ | RPL_LIST
+ | RPL_LISTEND
+ | RPL_CHANNELMODEIS
+ | RPL_UNIQOPIS
+ | RPL_NOTOPIC
+ | RPL_TOPIC
+ | RPL_INVITING
+ | RPL_SUMMONING
+ | RPL_INVITELIST
+ | RPL_ENDOFINVITELIST
+ | RPL_EXCEPTLIST
+ | RPL_ENDOFEXCEPTLIST
+ | RPL_VERSION
+ | RPL_WHOREPLY
+ | RPL_NAMREPLY
+ | RPL_LINKS
+ | RPL_ENDOFLINKS
+ | RPL_ENDOFNAMES
+ | RPL_BANLIST
+ | RPL_ENDOFBANLIST
+ | RPL_ENDOFWHOWAS
+ | RPL_INFO
+ | RPL_MOTD
+ | RPL_ENDOFINFO
+ | RPL_MOTDSTART
+ | RPL_ENDOFMOTD
+ | RPL_YOUREOPER
+ | RPL_REHASHING
+ | RPL_YOURESERVICE
+ | RPL_TIME
+ | RPL_USERSSTART
+ | RPL_USERS
+ | RPL_ENDOFUSERS
+ | RPL_NOUSERS
+
+ | ERR_NOSUCHNICK
+ | ERR_NOSUCHSERVER
+ | ERR_NOSUCHCHANNEL
+ | ERR_CANNOTSENDTOCHAN
+ | ERR_TOOMANYCHANNELS
+ | ERR_WASNOSUCHNICK
+ | ERR_TOOMANYTARGETS
+ | ERR_NOSUCHSERVICE
+ | ERR_NOORIGIN
+ | ERR_NORECIPIENT
+ | ERR_NOTEXTTOSEND
+ | ERR_NOTOPLEVEL
+ | ERR_WILDTOPLEVEL
+ | ERR_BADMASK
+ | ERR_UNKNOWNCOMMAND
+ | ERR_NOMOTD
+ | ERR_NOADMININFO
+ | ERR_FILEERROR
+ | ERR_NONICKNAMEGIVEN
+ | ERR_ERRONEUSNICKNAME
+ | ERR_NICKNAMEINUSE
+ | ERR_NICKCOLLISION
+ | ERR_UNAVAILRESOURCE
+ | ERR_USERNOTINCHANNEL
+ | ERR_NOTONCHANNEL
+ | ERR_USERONCHANNEL
+ | ERR_NOLOGIN
+ | ERR_SUMMONDISABLED
+ | ERR_USERSDISABLED
+ | ERR_NOTREGISTERED
+ | ERR_NEEDMOREPARAMS
+ | ERR_ALREADYREGISTRED
+ | ERR_NOPERMFORHOST
+ | ERR_PASSWDMISMATCH
+ | ERR_YOUREBANNEDCREEP
+ | ERR_YOUWILLBEBANNED
+ | ERR_KEYSET
+ | ERR_CHANNELISFULL
+ | ERR_UNKNOWNMODE
+ | ERR_INVITEONLYCHAN
+ | ERR_BANNEDFROMCHAN
+ | ERR_BADCHANNELKEY
+ | ERR_BADCHANMASK
+ | ERR_NOCHANMODES
+ | ERR_BANLISTFULL
+ | ERR_NOPRIVILEGES
+ | ERR_CHANOPRIVSNEEDED
+ | ERR_CANTKILLSERVER
+ | ERR_RESTRICTED
+ | ERR_UNIQOPPRIVSNEEDED
+ | ERR_NOOPERHOST
+ | ERR_UMODEUNKNOWNFLAG
+ | ERR_USERSDONTMATCH
+ deriving (Eq,Generic,Hashable,Show)
+
+instance ConvertibleStrings Text Command where
+ convertString = convert
+ where
+ convert s = M.lookupDefault (fallback s) s mTextCommand
+ fallback s =
+ case T.decimal s of
+ Right (i, "") -> UnknownReply i
+ _ -> UnknownCommand s
+
+instance ConvertibleStrings Command Text where
+ convertString = convert
+ where
+ convert c = M.lookupDefault (fallback c) c mCommandText
+ fallback = \case
+ UnknownCommand c -> c
+ UnknownReply i -> show3 i
+ x -> error ("no fallback for " <> show x)
+
+instance FromJSON Command where
+ parseJSON = \case
+ String t -> pure (convertString t)
+ invalid -> typeMismatch "Command" invalid
+
+instance FromJSONKey Command where
+ fromJSONKey = FromJSONKeyText convertString
+
+
+commands :: [(Text, Command)]
+commands =
+ [ ("ADMIN", ADMIN)
+ , ("AWAY", AWAY)
+ , ("CONNECT", CONNECT)
+ , ("DIE", DIE)
+ , ("ERROR", ERROR)
+ , ("INFO", INFO)
+ , ("INVITE", INVITE)
+ , ("ISON", ISON)
+ , ("JOIN", JOIN)
+ , ("KICK", KICK)
+ , ("KILL", KILL)
+ , ("LINKS", LINKS)
+ , ("LIST", LIST)
+ , ("LUSERS", LUSERS)
+ , ("MODE", MODE)
+ , ("MOTD", MOTD)
+ , ("NAMES", NAMES)
+ , ("NICK", NICK)
+ , ("NJOIN", NJOIN)
+ , ("NOTICE", NOTICE)
+ , ("OPER", OPER)
+ , ("PART", PART)
+ , ("PASS", PASS)
+ , ("PING", PING)
+ , ("PONG", PONG)
+ , ("PRIVMSG", PRIVMSG)
+ , ("QUIT", QUIT)
+ , ("REHASH", REHASH)
+ , ("RESTART", RESTART)
+ , ("SERVER", SERVER)
+ , ("SERVICE", SERVICE)
+ , ("SERVLIST", SERVLIST)
+ , ("SQUERY", SQUERY)
+ , ("SQUIRT", SQUIRT)
+ , ("SQUIT", SQUIT)
+ , ("STATS", STATS)
+ , ("SUMMON", SUMMON)
+ , ("TIME", TIME)
+ , ("TOPIC", TOPIC)
+ , ("TRACE", TRACE)
+ , ("USER", USER)
+ , ("USERHOST", USERHOST)
+ , ("USERS", USERS)
+ , ("VERSION", VERSION)
+ , ("WALLOPS", WALLOPS)
+ , ("WHO", WHO)
+ , ("WHOIS", WHOIS)
+ , ("WHOWAS", WHOWAS)
+ ]
+
+replies :: [(Int, Command)]
+replies =
+ [ (001, RPL_WELCOME)
+ , (002, RPL_YOURHOST)
+ , (003, RPL_CREATED)
+ , (004, RPL_MYINFO)
+ , (005, RPL_BOUNCE)
+
+ , (200, RPL_TRACELINK)
+ , (201, RPL_TRACECONNECTING)
+ , (202, RPL_TRACEHANDSHAKE)
+ , (203, RPL_TRACEUNKNOWN)
+ , (204, RPL_TRACEOPERATOR)
+ , (205, RPL_TRACEUSER)
+ , (206, RPL_TRACESERVER)
+ , (207, RPL_TRACESERVICE)
+ , (208, RPL_TRACENEWTYPE)
+ , (209, RPL_TRACECLASS)
+ , (210, RPL_TRACERECONNECT)
+ , (211, RPL_STATSLINKINFO)
+ , (212, RPL_STATSCOMMANDS)
+ , (219, RPL_ENDOFSTATS)
+ , (221, RPL_UMODEIS)
+ , (234, RPL_SERVLIST)
+ , (235, RPL_SERVLISTEND)
+ , (242, RPL_STATSUPTIME)
+ , (243, RPL_STATSOLINE)
+ , (251, RPL_LUSERCLIENT)
+ , (252, RPL_LUSEROP)
+ , (253, RPL_LUSERUNKNOWN)
+ , (254, RPL_LUSERCHANNELS)
+ , (255, RPL_LUSERME)
+ , (256, RPL_ADMINME)
+ , (257, RPL_ADMINLOC1)
+ , (258, RPL_ADMINLOC2)
+ , (259, RPL_ADMINEMAIL)
+ , (261, RPL_TRACELOG)
+ , (262, RPL_TRACEEND)
+ , (263, RPL_TRYAGAIN)
+ , (301, RPL_AWAY)
+ , (302, RPL_USERHOST)
+ , (303, RPL_ISON)
+ , (305, RPL_UNAWAY)
+ , (306, RPL_NOWAWAY)
+ , (311, RPL_WHOISUSER)
+ , (312, RPL_WHOISSERVER)
+ , (313, RPL_WHOISOPERATOR)
+ , (314, RPL_WHOWASUSER)
+ , (315, RPL_ENDOFWHO)
+ , (317, RPL_WHOISIDLE)
+ , (318, RPL_ENDOFWHOIS)
+ , (319, RPL_WHOISCHANNELS)
+ , (321, RPL_LISTSTART)
+ , (322, RPL_LIST)
+ , (323, RPL_LISTEND)
+ , (324, RPL_CHANNELMODEIS)
+ , (325, RPL_UNIQOPIS)
+ , (331, RPL_NOTOPIC)
+ , (332, RPL_TOPIC)
+ , (341, RPL_INVITING)
+ , (342, RPL_SUMMONING)
+ , (346, RPL_INVITELIST)
+ , (347, RPL_ENDOFINVITELIST)
+ , (348, RPL_EXCEPTLIST)
+ , (349, RPL_ENDOFEXCEPTLIST)
+ , (351, RPL_VERSION)
+ , (352, RPL_WHOREPLY)
+ , (353, RPL_NAMREPLY)
+ , (364, RPL_LINKS)
+ , (365, RPL_ENDOFLINKS)
+ , (366, RPL_ENDOFNAMES)
+ , (367, RPL_BANLIST)
+ , (368, RPL_ENDOFBANLIST)
+ , (369, RPL_ENDOFWHOWAS)
+ , (371, RPL_INFO)
+ , (372, RPL_MOTD)
+ , (374, RPL_ENDOFINFO)
+ , (375, RPL_MOTDSTART)
+ , (376, RPL_ENDOFMOTD)
+ , (381, RPL_YOUREOPER)
+ , (382, RPL_REHASHING)
+ , (383, RPL_YOURESERVICE)
+ , (391, RPL_TIME)
+ , (392, RPL_USERSSTART)
+ , (393, RPL_USERS)
+ , (394, RPL_ENDOFUSERS)
+ , (395, RPL_NOUSERS)
+
+ , (401, ERR_NOSUCHNICK)
+ , (402, ERR_NOSUCHSERVER)
+ , (403, ERR_NOSUCHCHANNEL)
+ , (404, ERR_CANNOTSENDTOCHAN)
+ , (405, ERR_TOOMANYCHANNELS)
+ , (406, ERR_WASNOSUCHNICK)
+ , (407, ERR_TOOMANYTARGETS)
+ , (408, ERR_NOSUCHSERVICE)
+ , (409, ERR_NOORIGIN)
+ , (411, ERR_NORECIPIENT)
+ , (412, ERR_NOTEXTTOSEND)
+ , (413, ERR_NOTOPLEVEL)
+ , (414, ERR_WILDTOPLEVEL)
+ , (415, ERR_BADMASK)
+ , (421, ERR_UNKNOWNCOMMAND)
+ , (422, ERR_NOMOTD)
+ , (423, ERR_NOADMININFO)
+ , (424, ERR_FILEERROR)
+ , (431, ERR_NONICKNAMEGIVEN)
+ , (432, ERR_ERRONEUSNICKNAME)
+ , (433, ERR_NICKNAMEINUSE)
+ , (436, ERR_NICKCOLLISION)
+ , (437, ERR_UNAVAILRESOURCE)
+ , (441, ERR_USERNOTINCHANNEL)
+ , (442, ERR_NOTONCHANNEL)
+ , (443, ERR_USERONCHANNEL)
+ , (444, ERR_NOLOGIN)
+ , (445, ERR_SUMMONDISABLED)
+ , (446, ERR_USERSDISABLED)
+ , (451, ERR_NOTREGISTERED)
+ , (461, ERR_NEEDMOREPARAMS)
+ , (462, ERR_ALREADYREGISTRED)
+ , (463, ERR_NOPERMFORHOST)
+ , (464, ERR_PASSWDMISMATCH)
+ , (465, ERR_YOUREBANNEDCREEP)
+ , (466, ERR_YOUWILLBEBANNED)
+ , (467, ERR_KEYSET)
+ , (471, ERR_CHANNELISFULL)
+ , (472, ERR_UNKNOWNMODE)
+ , (473, ERR_INVITEONLYCHAN)
+ , (474, ERR_BANNEDFROMCHAN)
+ , (475, ERR_BADCHANNELKEY)
+ , (476, ERR_BADCHANMASK)
+ , (477, ERR_NOCHANMODES)
+ , (478, ERR_BANLISTFULL)
+ , (481, ERR_NOPRIVILEGES)
+ , (482, ERR_CHANOPRIVSNEEDED)
+ , (483, ERR_CANTKILLSERVER)
+ , (484, ERR_RESTRICTED)
+ , (485, ERR_UNIQOPPRIVSNEEDED)
+ , (491, ERR_NOOPERHOST)
+ , (501, ERR_UMODEUNKNOWNFLAG)
+ , (502, ERR_USERSDONTMATCH)
+ ]
+
+mCommandText :: HashMap Command Text
+mCommandText =
+ M.fromList $
+ map (\(s,c) -> (c,s)) commands <>
+ map (\(i,c) -> (c,show3 i)) replies
+
+mTextCommand :: HashMap Text Command
+mTextCommand =
+ M.fromList $
+ map (\(s,c) -> (s,c)) commands <>
+ map (\(i,c) -> (show3 i,c)) replies
+
+show3 :: Int -> Text
+show3 i =
+ p <> s
+ where s = T.show i
+ p = T.replicate (3 - T.length s) "0"