Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add conduits to decode/encode to Network.IRC.Message #10

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions Network/IRC/Conduit.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ module Network.IRC.Conduit

-- *Conduits
, ircDecoder
, ircDecoderMessage
, ircLossyDecoder
, ircEncoder
, ircEncoderMessage
, floodProtector

-- *Networking
Expand Down Expand Up @@ -79,26 +81,39 @@ import Network.IRC.Conduit.Lens
import Network.TLS (ClientParams(..), ClientHooks(..), Supported(..), Version(..), defaultParamsClient)
import Network.TLS.Extra (ciphersuite_strong)

import qualified Network.IRC as I

-- *Conduits

-- |A conduit which takes as input bytestrings representing encoded
-- IRC messages, and decodes them to events. If decoding fails, the
-- original bytestring is just passed through.
-- IRC messages, and decodes them to events of type 'IrcEvent'.
-- If decoding fails, the original bytestring is just passed through.
ircDecoder :: Monad m => ConduitM ByteString (Either ByteString IrcEvent) m ()
ircDecoder = chunked .| awaitForever (yield . fromByteString)

-- |A conduit which takes as input bytestrings representing encoded
-- IRC messages, and decodes them to messages of type 'I.Message'.
-- If decoding fails, the original bytestring is just passed through.
ircDecoderMessage :: Monad m => ConduitM ByteString (Either ByteString I.Message) m ()
ircDecoderMessage = chunked .| awaitForever (yield . fromByteStringMessage)

-- |Like 'ircDecoder', but discards messages which could not be
-- decoded.
ircLossyDecoder :: Monad m => ConduitM ByteString IrcEvent m ()
ircLossyDecoder = chunked .| awaitForever lossy
where
lossy bs = either (\_ -> return ()) yield $ fromByteString bs

-- |A conduit which takes as input irc messages, and produces as
-- output the encoded bytestring representation.
-- |A conduit which takes as input irc messages of type 'IrcMessage',
-- and produces as output the encoded bytestring representation.
ircEncoder :: Monad m => ConduitM IrcMessage ByteString m ()
ircEncoder = awaitForever (yield . (<>"\r\n") . toByteString)

-- |A conduit which takes as input irc messages of type 'I.Message',
-- and produces as output the encoded bytestring representation.
ircEncoderMessage :: Monad m => ConduitM I.Message ByteString m ()
ircEncoderMessage = awaitForever (yield . (<>"\r\n") . I.encode)

-- |A conduit which rate limits output sent downstream. Awaiting on
-- this conduit will block, even if there is output ready, until the
-- time limit has passed.
Expand Down
3 changes: 3 additions & 0 deletions Network/IRC/Conduit/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ data Message a = Privmsg (Target a) (Either CTCPByteString a)
fromByteString :: ByteString -> Either ByteString IrcEvent
fromByteString bs = maybe (Left bs) Right $ uncurry (Event bs) <$> attemptDecode bs

fromByteStringMessage :: ByteString -> Either ByteString I.Message
fromByteStringMessage bs = maybe (Left bs) Right (I.decode bs)

-- |Attempt to decode a ByteString into a message, returning a Nothing
-- if either the source or the message can't be determined.
attemptDecode :: ByteString -> Maybe (IrcSource, IrcMessage)
Expand Down