{-# Language TemplateHaskell #-} {-| Module : Client.Hook Description : Hooks into the operation of the client. Copyright : (c) Dan Doel, 2016 License : ISC Maintainer : dan.doel@gmail.com This module defines types for hooking into the operation of the client. -} module Client.Hook ( -- | * Message hook results MessageResult(..) -- | * Message hooks , MessageHook(..) , messageHookName , messageHookStateful , messageHookAction , applyMessageHooks ) where import Control.Lens import Data.Text import Irc.Message -- | The possible results of a 'MessageHook' action. A hook can decline to -- handle a message ('PassMessage'), filter out a message ('OmitMessage'), -- or change a message into an arbitrary other message ('RemapMessage'). data MessageResult = PassMessage -- ^ continue processing | OmitMessage -- ^ stop processing and drop message | RemapMessage IrcMsg -- ^ stop processing and return new message -- 'PassMessage' is an identity element instance Semigroup MessageResult where PassMessage <> r = r l <> _ = l instance Monoid MessageResult where mempty = PassMessage mappend = (<>) maybeFromResult :: IrcMsg -> MessageResult -> Maybe IrcMsg maybeFromResult original PassMessage = Just original maybeFromResult _ OmitMessage = Nothing maybeFromResult _ (RemapMessage new) = Just new -- A hook into the IRC message portion of the event loop. 'MessageHook's are -- able to filter out or alter 'IrcMsg's, and may do so in a way that either -- affects the overall 'ClientState' or just the chat view. data MessageHook = MessageHook { _messageHookName :: Text -- ^ Identifying name for the hook , _messageHookStateful :: Bool -- ^ Whether the remapping should affect client state , _messageHookAction :: IrcMsg -> MessageResult -- ^ (Partial) message remapping action } makeLenses ''MessageHook -- | Apply the given message hooks to an 'IrcMsg'. The hooks are tried in -- order until one handles the message. A 'Nothing' result means the message was -- filtered out by a hook. A 'Just' result contains the actual 'IrcMsg' to be -- processed. applyMessageHooks :: [MessageHook] -> IrcMsg -> Maybe IrcMsg applyMessageHooks hs msg = maybeFromResult msg $ foldMap (\h -> view messageHookAction h msg) hs