{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TupleSections #-}
module Network.IRC.Conduit.Internal where
import Control.Applicative ((<$>))
import Control.Arrow ((&&&))
import Data.ByteString (ByteString, isSuffixOf, singleton,
unpack)
import Data.Char (ord)
import Data.Conduit (ConduitM, await, yield)
import Data.Maybe (isJust, listToMaybe)
import Data.Monoid ((<>))
import Data.Profunctor (Choice)
import Data.String (fromString)
import Network.IRC.CTCP (CTCPByteString, getUnderlyingByteString,
orCTCP)
import Text.Read (readMaybe)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import qualified Network.IRC as I
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
type Lens' s a = Lens s s a a
type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t)
type Prism' s a = Prism s s a a
chunked :: Monad m => ConduitM ByteString ByteString m ()
chunked :: ConduitM ByteString ByteString m ()
chunked = ByteString -> ConduitM ByteString ByteString m ()
forall (m :: * -> *).
Monad m =>
ByteString -> ConduitT ByteString ByteString m ()
chunked' ByteString
""
where
chunked' :: ByteString -> ConduitT ByteString ByteString m ()
chunked' !ByteString
leftover = do
Maybe ByteString
val <- ConduitT ByteString ByteString m (Maybe ByteString)
forall (m :: * -> *) i. Monad m => Consumer i m (Maybe i)
await
case Maybe ByteString
val of
Just ByteString
val' ->
let
carriage :: Word8
carriage = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
'\r'
newline :: Word8
newline = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
'\n'
bytes :: ByteString
bytes = (Word8 -> Bool) -> ByteString -> ByteString
B.filter (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/=Word8
carriage) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
leftover ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
val'
splitted :: [ByteString]
splitted = Word8 -> ByteString -> [ByteString]
B.split Word8
newline ByteString
bytes
([ByteString]
toyield, ByteString
remainder)
| Word8 -> ByteString
singleton Word8
newline ByteString -> ByteString -> Bool
`isSuffixOf` ByteString
bytes = ([ByteString]
splitted, ByteString
"")
| Bool
otherwise = [ByteString] -> [ByteString]
forall a. [a] -> [a]
init ([ByteString] -> [ByteString])
-> ([ByteString] -> ByteString)
-> [ByteString]
-> ([ByteString], ByteString)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& [ByteString] -> ByteString
forall a. [a] -> a
last ([ByteString] -> ([ByteString], ByteString))
-> [ByteString] -> ([ByteString], ByteString)
forall a b. (a -> b) -> a -> b
$ [ByteString]
splitted
in do
(ByteString -> ConduitT ByteString ByteString m ())
-> [ByteString] -> ConduitT ByteString ByteString m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ByteString -> ConduitT ByteString ByteString m ()
forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ([ByteString] -> ConduitT ByteString ByteString m ())
-> [ByteString] -> ConduitT ByteString ByteString m ()
forall a b. (a -> b) -> a -> b
$ (ByteString -> Bool) -> [ByteString] -> [ByteString]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (ByteString -> Bool) -> ByteString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Bool
B.null) [ByteString]
toyield
ByteString -> ConduitT ByteString ByteString m ()
chunked' ByteString
remainder
Maybe ByteString
Nothing -> () -> ConduitT ByteString ByteString m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
type ChannelName a = a
type NickName a = a
type ServerName a = a
type Reason a = Maybe a
type IsModeSet = Bool
type ModeFlag a = a
type ModeArg a = a
type NumericArg a = a
type Target a = a
type IrcEvent = Event ByteString
type IrcSource = Source ByteString
type IrcMessage = Message ByteString
data Event a = Event
{ Event a -> ByteString
_raw :: ByteString
, Event a -> Source a
_source :: Source a
, Event a -> Message a
_message :: Message a
}
deriving (Event a -> Event a -> Bool
(Event a -> Event a -> Bool)
-> (Event a -> Event a -> Bool) -> Eq (Event a)
forall a. Eq a => Event a -> Event a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Event a -> Event a -> Bool
$c/= :: forall a. Eq a => Event a -> Event a -> Bool
== :: Event a -> Event a -> Bool
$c== :: forall a. Eq a => Event a -> Event a -> Bool
Eq, a -> Event b -> Event a
(a -> b) -> Event a -> Event b
(forall a b. (a -> b) -> Event a -> Event b)
-> (forall a b. a -> Event b -> Event a) -> Functor Event
forall a b. a -> Event b -> Event a
forall a b. (a -> b) -> Event a -> Event b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Event b -> Event a
$c<$ :: forall a b. a -> Event b -> Event a
fmap :: (a -> b) -> Event a -> Event b
$cfmap :: forall a b. (a -> b) -> Event a -> Event b
Functor, Int -> Event a -> ShowS
[Event a] -> ShowS
Event a -> String
(Int -> Event a -> ShowS)
-> (Event a -> String) -> ([Event a] -> ShowS) -> Show (Event a)
forall a. Show a => Int -> Event a -> ShowS
forall a. Show a => [Event a] -> ShowS
forall a. Show a => Event a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Event a] -> ShowS
$cshowList :: forall a. Show a => [Event a] -> ShowS
show :: Event a -> String
$cshow :: forall a. Show a => Event a -> String
showsPrec :: Int -> Event a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Event a -> ShowS
Show)
data Source a = User (NickName a)
| Channel (ChannelName a) (NickName a)
| Server (ServerName a)
deriving (Source a -> Source a -> Bool
(Source a -> Source a -> Bool)
-> (Source a -> Source a -> Bool) -> Eq (Source a)
forall a. Eq a => Source a -> Source a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Source a -> Source a -> Bool
$c/= :: forall a. Eq a => Source a -> Source a -> Bool
== :: Source a -> Source a -> Bool
$c== :: forall a. Eq a => Source a -> Source a -> Bool
Eq, a -> Source b -> Source a
(a -> b) -> Source a -> Source b
(forall a b. (a -> b) -> Source a -> Source b)
-> (forall a b. a -> Source b -> Source a) -> Functor Source
forall a b. a -> Source b -> Source a
forall a b. (a -> b) -> Source a -> Source b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Source b -> Source a
$c<$ :: forall a b. a -> Source b -> Source a
fmap :: (a -> b) -> Source a -> Source b
$cfmap :: forall a b. (a -> b) -> Source a -> Source b
Functor, Int -> Source a -> ShowS
[Source a] -> ShowS
Source a -> String
(Int -> Source a -> ShowS)
-> (Source a -> String) -> ([Source a] -> ShowS) -> Show (Source a)
forall a. Show a => Int -> Source a -> ShowS
forall a. Show a => [Source a] -> ShowS
forall a. Show a => Source a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Source a] -> ShowS
$cshowList :: forall a. Show a => [Source a] -> ShowS
show :: Source a -> String
$cshow :: forall a. Show a => Source a -> String
showsPrec :: Int -> Source a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Source a -> ShowS
Show)
data Message a = Privmsg (Target a) (Either CTCPByteString a)
| Notice (Target a) (Either CTCPByteString a)
| Nick (NickName a)
| Join (ChannelName a)
| Part (ChannelName a) (Reason a)
| Quit (Reason a)
| Mode (Target a) IsModeSet [ModeFlag a] [ModeArg a]
| Topic (ChannelName a) a
| Invite (ChannelName a) (NickName a)
| Kick (ChannelName a) (NickName a) (Reason a)
| Ping (ServerName a) (Maybe (ServerName a))
| Pong (ServerName a)
| Numeric Int [NumericArg a]
| RawMsg a
deriving (Message a -> Message a -> Bool
(Message a -> Message a -> Bool)
-> (Message a -> Message a -> Bool) -> Eq (Message a)
forall a. Eq a => Message a -> Message a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Message a -> Message a -> Bool
$c/= :: forall a. Eq a => Message a -> Message a -> Bool
== :: Message a -> Message a -> Bool
$c== :: forall a. Eq a => Message a -> Message a -> Bool
Eq, a -> Message b -> Message a
(a -> b) -> Message a -> Message b
(forall a b. (a -> b) -> Message a -> Message b)
-> (forall a b. a -> Message b -> Message a) -> Functor Message
forall a b. a -> Message b -> Message a
forall a b. (a -> b) -> Message a -> Message b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Message b -> Message a
$c<$ :: forall a b. a -> Message b -> Message a
fmap :: (a -> b) -> Message a -> Message b
$cfmap :: forall a b. (a -> b) -> Message a -> Message b
Functor, Int -> Message a -> ShowS
[Message a] -> ShowS
Message a -> String
(Int -> Message a -> ShowS)
-> (Message a -> String)
-> ([Message a] -> ShowS)
-> Show (Message a)
forall a. Show a => Int -> Message a -> ShowS
forall a. Show a => [Message a] -> ShowS
forall a. Show a => Message a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Message a] -> ShowS
$cshowList :: forall a. Show a => [Message a] -> ShowS
show :: Message a -> String
$cshow :: forall a. Show a => Message a -> String
showsPrec :: Int -> Message a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Message a -> ShowS
Show)
fromByteString :: ByteString -> Either ByteString IrcEvent
fromByteString :: ByteString -> Either ByteString IrcEvent
fromByteString ByteString
bs = Either ByteString IrcEvent
-> (IrcEvent -> Either ByteString IrcEvent)
-> Maybe IrcEvent
-> Either ByteString IrcEvent
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (ByteString -> Either ByteString IrcEvent
forall a b. a -> Either a b
Left ByteString
bs) IrcEvent -> Either ByteString IrcEvent
forall a b. b -> Either a b
Right (Maybe IrcEvent -> Either ByteString IrcEvent)
-> Maybe IrcEvent -> Either ByteString IrcEvent
forall a b. (a -> b) -> a -> b
$ (Source ByteString -> Message ByteString -> IrcEvent)
-> (Source ByteString, Message ByteString) -> IrcEvent
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (ByteString -> Source ByteString -> Message ByteString -> IrcEvent
forall a. ByteString -> Source a -> Message a -> Event a
Event ByteString
bs) ((Source ByteString, Message ByteString) -> IrcEvent)
-> Maybe (Source ByteString, Message ByteString) -> Maybe IrcEvent
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Maybe (Source ByteString, Message ByteString)
attemptDecode ByteString
bs
attemptDecode :: ByteString -> Maybe (IrcSource, IrcMessage)
attemptDecode :: ByteString -> Maybe (Source ByteString, Message ByteString)
attemptDecode ByteString
bs = ByteString -> Maybe Message
I.decode ByteString
bs Maybe Message
-> (Message -> Maybe (Source ByteString, Message ByteString))
-> Maybe (Source ByteString, Message ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Message -> Maybe (Source ByteString, Message ByteString)
decode'
where
decode' :: Message -> Maybe (Source ByteString, Message ByteString)
decode' Message
msg = case Message
msg of
I.Message (Just (I.NickName ByteString
n Maybe ByteString
_ Maybe ByteString
_)) ByteString
"PRIVMSG" [ByteString
t, ByteString
m] | ByteString -> Bool
isChan ByteString
t -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> ByteString -> Source ByteString
forall a. ChannelName a -> ChannelName a -> Source (ChannelName a)
Channel ByteString
t ByteString
n, ByteString -> ByteString -> Message ByteString
privmsg ByteString
t ByteString
m)
| Bool
otherwise -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> Source ByteString
forall a. ChannelName a -> Source (ChannelName a)
User ByteString
n, ByteString -> ByteString -> Message ByteString
privmsg ByteString
t ByteString
m)
I.Message (Just (I.NickName ByteString
n Maybe ByteString
_ Maybe ByteString
_)) ByteString
"NOTICE" [ByteString
t, ByteString
m] | ByteString -> Bool
isChan ByteString
t -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> ByteString -> Source ByteString
forall a. ChannelName a -> ChannelName a -> Source (ChannelName a)
Channel ByteString
t ByteString
n, ByteString -> ByteString -> Message ByteString
notice ByteString
t ByteString
m)
| Bool
otherwise -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> Source ByteString
forall a. ChannelName a -> Source (ChannelName a)
User ByteString
n, ByteString -> ByteString -> Message ByteString
notice ByteString
t ByteString
m)
I.Message (Just (I.NickName ByteString
n Maybe ByteString
_ Maybe ByteString
_)) ByteString
"NICK" [ByteString
n'] -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> Source ByteString
forall a. ChannelName a -> Source (ChannelName a)
User ByteString
n, ByteString -> Message ByteString
forall a. NickName a -> Message (NickName a)
Nick ByteString
n')
I.Message (Just (I.NickName ByteString
n Maybe ByteString
_ Maybe ByteString
_)) ByteString
"JOIN" [ByteString
c] -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> ByteString -> Source ByteString
forall a. ChannelName a -> ChannelName a -> Source (ChannelName a)
Channel ByteString
c ByteString
n, ByteString -> Message ByteString
forall a. NickName a -> Message (NickName a)
Join ByteString
c)
I.Message (Just (I.NickName ByteString
n Maybe ByteString
_ Maybe ByteString
_)) ByteString
"PART" (ByteString
c:[ByteString]
r) -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> ByteString -> Source ByteString
forall a. ChannelName a -> ChannelName a -> Source (ChannelName a)
Channel ByteString
c ByteString
n, ByteString -> Maybe ByteString -> Message ByteString
forall a. NickName a -> Reason (NickName a) -> Message (NickName a)
Part ByteString
c (Maybe ByteString -> Message ByteString)
-> Maybe ByteString -> Message ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> Maybe ByteString
forall a. [a] -> Maybe a
listToMaybe [ByteString]
r)
I.Message (Just (I.NickName ByteString
n Maybe ByteString
_ Maybe ByteString
_)) ByteString
"QUIT" [ByteString]
r -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> Source ByteString
forall a. ChannelName a -> Source (ChannelName a)
User ByteString
n, Maybe ByteString -> Message ByteString
forall a. Reason (NickName a) -> Message (NickName a)
Quit (Maybe ByteString -> Message ByteString)
-> Maybe ByteString -> Message ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> Maybe ByteString
forall a. [a] -> Maybe a
listToMaybe [ByteString]
r)
I.Message (Just (I.NickName ByteString
n Maybe ByteString
_ Maybe ByteString
_)) ByteString
"KICK" (ByteString
c:ByteString
u:[ByteString]
r) -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> ByteString -> Source ByteString
forall a. ChannelName a -> ChannelName a -> Source (ChannelName a)
Channel ByteString
c ByteString
n, ByteString -> ByteString -> Maybe ByteString -> Message ByteString
forall a.
NickName a
-> NickName a -> Reason (NickName a) -> Message (NickName a)
Kick ByteString
c ByteString
u (Maybe ByteString -> Message ByteString)
-> Maybe ByteString -> Message ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> Maybe ByteString
forall a. [a] -> Maybe a
listToMaybe [ByteString]
r)
I.Message (Just (I.NickName ByteString
n Maybe ByteString
_ Maybe ByteString
_)) ByteString
"INVITE" [ByteString
_, ByteString
c] -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> Source ByteString
forall a. ChannelName a -> Source (ChannelName a)
User ByteString
n, ByteString -> ByteString -> Message ByteString
forall a. NickName a -> NickName a -> Message (NickName a)
Invite ByteString
c ByteString
n)
I.Message (Just (I.NickName ByteString
n Maybe ByteString
_ Maybe ByteString
_)) ByteString
"TOPIC" [ByteString
c, ByteString
t] -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> ByteString -> Source ByteString
forall a. ChannelName a -> ChannelName a -> Source (ChannelName a)
Channel ByteString
c ByteString
n, ByteString -> ByteString -> Message ByteString
forall a. NickName a -> NickName a -> Message (NickName a)
Topic ByteString
c ByteString
t)
I.Message (Just (I.NickName ByteString
n Maybe ByteString
_ Maybe ByteString
_)) ByteString
"MODE" (ByteString
t:ByteString
fs:[ByteString]
as) | ByteString
n ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
t -> (ByteString -> Source ByteString
forall a. ChannelName a -> Source (ChannelName a)
User ByteString
n,) (Message ByteString -> (Source ByteString, Message ByteString))
-> Maybe (Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString
-> ByteString -> [ByteString] -> Maybe (Message ByteString)
mode ByteString
t ByteString
fs [ByteString]
as
| Bool
otherwise -> (ByteString -> ByteString -> Source ByteString
forall a. ChannelName a -> ChannelName a -> Source (ChannelName a)
Channel ByteString
t ByteString
n,) (Message ByteString -> (Source ByteString, Message ByteString))
-> Maybe (Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString
-> ByteString -> [ByteString] -> Maybe (Message ByteString)
mode ByteString
t ByteString
fs [ByteString]
as
I.Message (Just (I.Server ByteString
s)) ByteString
"PING" (ByteString
s1:[ByteString]
s2) -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> Source ByteString
forall a. ChannelName a -> Source (ChannelName a)
Server ByteString
s, ByteString -> Maybe ByteString -> Message ByteString
forall a. NickName a -> Reason (NickName a) -> Message (NickName a)
Ping ByteString
s1 (Maybe ByteString -> Message ByteString)
-> Maybe ByteString -> Message ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> Maybe ByteString
forall a. [a] -> Maybe a
listToMaybe [ByteString]
s2)
I.Message Maybe Prefix
Nothing ByteString
"PING" (ByteString
s1:[ByteString]
s2) -> (Source ByteString, Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall a. a -> Maybe a
Just (ByteString -> Source ByteString
forall a. ChannelName a -> Source (ChannelName a)
Server ByteString
s1, ByteString -> Maybe ByteString -> Message ByteString
forall a. NickName a -> Reason (NickName a) -> Message (NickName a)
Ping ByteString
s1 (Maybe ByteString -> Message ByteString)
-> Maybe ByteString -> Message ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> Maybe ByteString
forall a. [a] -> Maybe a
listToMaybe [ByteString]
s2)
I.Message (Just (I.Server ByteString
s)) ByteString
n [ByteString]
args | ByteString -> Bool
isNumeric ByteString
n -> (ByteString -> Source ByteString
forall a. ChannelName a -> Source (ChannelName a)
Server ByteString
s,) (Message ByteString -> (Source ByteString, Message ByteString))
-> Maybe (Message ByteString)
-> Maybe (Source ByteString, Message ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> [ByteString] -> Maybe (Message ByteString)
forall a.
ByteString -> [NumericArg a] -> Maybe (Message (NumericArg a))
numeric ByteString
n [ByteString]
args
Message
_ -> Maybe (Source ByteString, Message ByteString)
forall a. Maybe a
Nothing
isChan :: ByteString -> Bool
isChan ByteString
t = Int -> ByteString -> ByteString
B.take Int
1 ByteString
t ByteString -> [ByteString] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ByteString
"#", ByteString
"&", ByteString
"+", ByteString
"!"]
privmsg :: ByteString -> ByteString -> Message ByteString
privmsg ByteString
t = ByteString
-> Either CTCPByteString ByteString -> Message ByteString
forall a.
NickName a
-> Either CTCPByteString (NickName a) -> Message (NickName a)
Privmsg ByteString
t (Either CTCPByteString ByteString -> Message ByteString)
-> (ByteString -> Either CTCPByteString ByteString)
-> ByteString
-> Message ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Either CTCPByteString ByteString
forall a b. b -> Either a b
Right (ByteString -> Either CTCPByteString ByteString)
-> (CTCPByteString -> Either CTCPByteString ByteString)
-> ByteString
-> Either CTCPByteString ByteString
forall a.
(ByteString -> a) -> (CTCPByteString -> a) -> ByteString -> a
`orCTCP` CTCPByteString -> Either CTCPByteString ByteString
forall a b. a -> Either a b
Left)
notice :: ByteString -> ByteString -> Message ByteString
notice ByteString
t = ByteString
-> Either CTCPByteString ByteString -> Message ByteString
forall a.
NickName a
-> Either CTCPByteString (NickName a) -> Message (NickName a)
Notice ByteString
t (Either CTCPByteString ByteString -> Message ByteString)
-> (ByteString -> Either CTCPByteString ByteString)
-> ByteString
-> Message ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Either CTCPByteString ByteString
forall a b. b -> Either a b
Right (ByteString -> Either CTCPByteString ByteString)
-> (CTCPByteString -> Either CTCPByteString ByteString)
-> ByteString
-> Either CTCPByteString ByteString
forall a.
(ByteString -> a) -> (CTCPByteString -> a) -> ByteString -> a
`orCTCP` CTCPByteString -> Either CTCPByteString ByteString
forall a b. a -> Either a b
Left)
mode :: ByteString
-> ByteString -> [ByteString] -> Maybe (Message ByteString)
mode ByteString
t ByteString
fs [ByteString]
as = case ByteString -> [Word8]
unpack ByteString
fs of
(Word8
f:[Word8]
fs') | Word8
f Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
'+') -> Message ByteString -> Maybe (Message ByteString)
forall a. a -> Maybe a
Just (Message ByteString -> Maybe (Message ByteString))
-> Message ByteString -> Maybe (Message ByteString)
forall a b. (a -> b) -> a -> b
$ ByteString
-> Bool -> [ByteString] -> [ByteString] -> Message ByteString
forall a.
NickName a
-> Bool -> [NickName a] -> [NickName a] -> Message (NickName a)
Mode ByteString
t Bool
True ((Word8 -> ByteString) -> [Word8] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Word8 -> ByteString
singleton [Word8]
fs') [ByteString]
as
| Word8
f Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
'-') -> Message ByteString -> Maybe (Message ByteString)
forall a. a -> Maybe a
Just (Message ByteString -> Maybe (Message ByteString))
-> Message ByteString -> Maybe (Message ByteString)
forall a b. (a -> b) -> a -> b
$ ByteString
-> Bool -> [ByteString] -> [ByteString] -> Message ByteString
forall a.
NickName a
-> Bool -> [NickName a] -> [NickName a] -> Message (NickName a)
Mode ByteString
t Bool
False ((Word8 -> ByteString) -> [Word8] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Word8 -> ByteString
singleton [Word8]
fs') [ByteString]
as
[Word8]
_ -> Maybe (Message ByteString)
forall a. Maybe a
Nothing
isNumeric :: ByteString -> Bool
isNumeric = Maybe Int -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Int -> Bool)
-> (ByteString -> Maybe Int) -> ByteString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe :: String -> Maybe Int) (String -> Maybe Int)
-> (ByteString -> String) -> ByteString -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> String
B8.unpack
numeric :: ByteString -> [NumericArg a] -> Maybe (Message (NumericArg a))
numeric ByteString
n [NumericArg a]
args = (Int -> [NumericArg a] -> Message (NumericArg a))
-> [NumericArg a] -> Int -> Message (NumericArg a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> [NumericArg a] -> Message (NumericArg a)
forall a. Int -> [NickName a] -> Message (NickName a)
Numeric [NumericArg a]
args (Int -> Message (NumericArg a))
-> Maybe Int -> Maybe (Message (NumericArg a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe (ByteString -> String
B8.unpack ByteString
n)
toByteString :: IrcMessage -> ByteString
toByteString :: Message ByteString -> ByteString
toByteString (Privmsg ByteString
t (Left CTCPByteString
ctcpbs)) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"PRIVMSG" [ByteString
t, CTCPByteString -> ByteString
getUnderlyingByteString CTCPByteString
ctcpbs]
toByteString (Privmsg ByteString
t (Right ByteString
bs)) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"PRIVMSG" [ByteString
t, ByteString
bs]
toByteString (Notice ByteString
t (Left CTCPByteString
ctcpbs)) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"NOTICE" [ByteString
t, CTCPByteString -> ByteString
getUnderlyingByteString CTCPByteString
ctcpbs]
toByteString (Notice ByteString
t (Right ByteString
bs)) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"NOTICE" [ByteString
t, ByteString
bs]
toByteString (Nick ByteString
n) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"NICK" [ByteString
n]
toByteString (Join ByteString
c) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"JOIN" [ByteString
c]
toByteString (Part ByteString
c (Just ByteString
r)) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"PART" [ByteString
c, ByteString
r]
toByteString (Part ByteString
c Maybe ByteString
Nothing) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"PART" [ByteString
c]
toByteString (Quit (Just ByteString
r)) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"QUIT" [ByteString
r]
toByteString (Quit Maybe ByteString
Nothing) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"QUIT" []
toByteString (Mode ByteString
t Bool
True [ByteString]
ms [ByteString]
as) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"MODE" ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
t ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: (ByteString
"+" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> [ByteString] -> ByteString
B.concat [ByteString]
ms) ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
as
toByteString (Mode ByteString
t Bool
False [ByteString]
ms [ByteString]
as) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"MODE" ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
t ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: (ByteString
"-" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> [ByteString] -> ByteString
B.concat [ByteString]
ms) ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
as
toByteString (Invite ByteString
c ByteString
n) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"INVITE" [ByteString
c, ByteString
n]
toByteString (Topic ByteString
c ByteString
bs) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"TOPIC" [ByteString
c, ByteString
bs]
toByteString (Kick ByteString
c ByteString
n (Just ByteString
r)) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"KICK" [ByteString
c, ByteString
n, ByteString
r]
toByteString (Kick ByteString
c ByteString
n Maybe ByteString
Nothing) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"KICK" [ByteString
c, ByteString
n]
toByteString (Ping ByteString
s1 (Just ByteString
s2)) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"PING" [ByteString
s1, ByteString
s2]
toByteString (Ping ByteString
s1 Maybe ByteString
Nothing) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"PING" [ByteString
s1]
toByteString (Pong ByteString
s) = ByteString -> [ByteString] -> ByteString
mkMessage ByteString
"PONG" [ByteString
s]
toByteString (Numeric Int
n [ByteString]
as) = ByteString -> [ByteString] -> ByteString
mkMessage (String -> ByteString
forall a. IsString a => String -> a
fromString (String -> ByteString) -> String -> ByteString
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show Int
n) [ByteString]
as
toByteString (RawMsg ByteString
bs) = ByteString
bs
mkMessage :: ByteString -> [ByteString] -> ByteString
mkMessage :: ByteString -> [ByteString] -> ByteString
mkMessage ByteString
cmd = Message -> ByteString
I.encode (Message -> ByteString)
-> ([ByteString] -> Message) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Prefix -> ByteString -> [ByteString] -> Message
I.Message Maybe Prefix
forall a. Maybe a
Nothing ByteString
cmd
rawMessage :: ByteString
-> [ByteString]
-> IrcMessage
rawMessage :: ByteString -> [ByteString] -> Message ByteString
rawMessage ByteString
cmd = ByteString -> Message ByteString
forall a. NickName a -> Message (NickName a)
RawMsg (ByteString -> Message ByteString)
-> ([ByteString] -> ByteString)
-> [ByteString]
-> Message ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString] -> ByteString
mkMessage ByteString
cmd