diff --git a/source/Network/Xmpp.hs b/source/Network/Xmpp.hs index 00ae251..aee731d 100644 --- a/source/Network/Xmpp.hs +++ b/source/Network/Xmpp.hs @@ -15,7 +15,7 @@ -- presence-aware clients and servers. -- -- Pontarius XMPP is an XMPP client library, implementing the core capabilities --- of XMPP (RFC 6120): setup and teardown of XML streams, channel encryption, +-- of XMPP (RFC 6120): setup and tear-down of XML streams, channel encryption, -- authentication, error handling, and communication primitives for messaging. -- -- For low-level access to Pontarius XMPP, see the "Network.Xmpp.Internal" @@ -32,7 +32,7 @@ -- -- Defining 'AuthData' can be a bit unwieldy, so 'simpleAuth' gives us a -- reasonable default. Though, for improved security, we should consider --- restricting the mecahnisms to 'scramSha1' whenever we can. +-- restricting the mechanisms to 'scramSha1' whenever we can. -- -- Next we have to set the presence to online, otherwise we won't be able to -- send or receive stanzas to/from other entities. @@ -137,9 +137,13 @@ module Network.Xmpp -- *** Receiving , pullMessage , getMessage + , getMessageA , waitForMessage + , waitForMessageA , waitForMessageError + , waitForMessageErrorA , filterMessages + , filterMessagesA -- ** Presence -- | XMPP includes the ability for an entity to advertise its network -- availability, or "presence", to other entities. In XMPP, this availability diff --git a/source/Network/Xmpp/Concurrent/Basic.hs b/source/Network/Xmpp/Concurrent/Basic.hs index 8f07668..b1519f3 100644 --- a/source/Network/Xmpp/Concurrent/Basic.hs +++ b/source/Network/Xmpp/Concurrent/Basic.hs @@ -39,7 +39,10 @@ getStanzaChan session = stanzaCh session getStanza :: Session -> IO (Stanza, [Annotation]) getStanza session = atomically . readTChan $ stanzaCh session --- | Create a new session object with the inbound channel duplicated +-- | Duplicate the inbound channel of the session object. Most receiving +-- functions discard stanzas they are not interested in from the inbound +-- channel. Duplicating the channel ensures that those stanzas can aren't lost +-- and can still be handled somewhere else. dupSession :: Session -> IO Session dupSession session = do stanzaCh' <- atomically $ dupTChan (stanzaCh session) diff --git a/source/Network/Xmpp/Concurrent/Message.hs b/source/Network/Xmpp/Concurrent/Message.hs index 7fe5aa5..a83d680 100644 --- a/source/Network/Xmpp/Concurrent/Message.hs +++ b/source/Network/Xmpp/Concurrent/Message.hs @@ -7,8 +7,8 @@ import Control.Concurrent.STM import Network.Xmpp.Types import Network.Xmpp.Concurrent.Basic --- | Read an element from the inbound stanza channel, discardes any --- non-Message stanzas from the channel +-- | Draw and discard stanzas from the inbound channel until a message or +-- message error is found. Returns the message or message error with annotations. pullMessage :: Session -> IO (Either (Annotated MessageError) (Annotated Message)) pullMessage session = do (stanza, as) <- atomically . readTChan $ stanzaCh session @@ -17,16 +17,18 @@ pullMessage session = do MessageErrorS e -> return $ Left (e, as) _ -> pullMessage session --- | Get the next received message with plugin Annotations +-- | Draw and discard stanzas from the inbound channel until a message is +-- found. Returns the message with annotations. getMessageA :: Session -> IO (Annotated Message) getMessageA = waitForMessageA (const True) --- | Get the next received message +-- | Draw and discard stanzas from the inbound channel until a message is +-- found. Returns the message. getMessage :: Session -> IO Message getMessage s = fst <$> getMessageA s --- | Pulls a (non-error) message and returns it if the given predicate returns --- @True@. +-- | Draw and discard stanzas from the inbound channel until a message matching +-- the given predicate is found. Returns the matching message with annotations. waitForMessageA :: (Annotated Message -> Bool) -> Session -> IO (Annotated Message) waitForMessageA f session = do s <- pullMessage session @@ -35,10 +37,14 @@ waitForMessageA f session = do Right m | f m -> return m | otherwise -> waitForMessageA f session +-- | Draw and discard stanzas from the inbound channel until a message matching +-- the given predicate is found. Returns the matching message. waitForMessage :: (Message -> Bool) -> Session -> IO Message waitForMessage f s = fst <$> waitForMessageA (f . fst) s --- | Pulls an error message and returns it if the given predicate returns @True@. +-- | Draw and discard stanzas from the inbound channel until a message error +-- matching the given predicate is found. Returns the matching message error with +-- annotations. waitForMessageErrorA :: (Annotated MessageError -> Bool) -> Session -> IO (Annotated MessageError) @@ -49,10 +55,14 @@ waitForMessageErrorA f session = do Left m | f m -> return m | otherwise -> waitForMessageErrorA f session +-- | Draw and discard stanzas from the inbound channel until a message error +-- matching the given predicate is found. Returns the matching message error waitForMessageError :: (MessageError -> Bool) -> Session -> IO MessageError waitForMessageError f s = fst <$> waitForMessageErrorA (f . fst) s --- | Pulls a message and returns it if the given predicate returns @True@. +-- | Draw and discard stanzas from the inbound channel until a message or +-- message error matching the given respective predicate is found. Returns the +-- matching message or message error with annotations filterMessagesA :: (Annotated MessageError -> Bool) -> (Annotated Message -> Bool) -> Session -> IO (Either (Annotated MessageError) @@ -65,6 +75,9 @@ filterMessagesA f g session = do Right m | g m -> return $ Right m | otherwise -> filterMessagesA f g session +-- | Draw and discard stanzas from the inbound channel until a message or +-- message error matching the given respective predicate is found. Returns the +-- matching message or message error. filterMessages :: (MessageError -> Bool) -> (Message -> Bool) -> Session diff --git a/source/Network/Xmpp/Concurrent/Presence.hs b/source/Network/Xmpp/Concurrent/Presence.hs index 39b0392..f261668 100644 --- a/source/Network/Xmpp/Concurrent/Presence.hs +++ b/source/Network/Xmpp/Concurrent/Presence.hs @@ -7,8 +7,8 @@ import Network.Xmpp.Types import Network.Xmpp.Concurrent.Types import Network.Xmpp.Concurrent.Basic --- | Read an element from the inbound stanza channel, discardes any non-Presence --- stanzas from the channel +-- | Read a presence stanza from the inbound stanza channel, discards any other +-- stanzas. Returns the presence stanza with annotations. pullPresenceA :: Session -> IO (Either (Annotated PresenceError) (Annotated Presence)) pullPresenceA session = do @@ -18,11 +18,12 @@ pullPresenceA session = do PresenceErrorS e -> return $ Left (e, as) _ -> pullPresenceA session +-- | Read a presence stanza from the inbound stanza channel, discards any other +-- stanzas. Returns the presence stanza. pullPresence :: Session -> IO (Either PresenceError Presence) pullPresence s = either (Left . fst) (Right . fst) <$> pullPresenceA s --- | Pulls a (non-error) presence and returns it if the given predicate returns --- @True@. +-- | Draw and discard stanzas from the inbound channel until a presence stanza matching the given predicate is found. Return the presence stanza with annotations. waitForPresenceA :: (Annotated Presence -> Bool) -> Session -> IO (Annotated Presence) @@ -33,6 +34,7 @@ waitForPresenceA f session = do Right m | f m -> return m | otherwise -> waitForPresenceA f session +-- | Draw and discard stanzas from the inbound channel until a presence stanza matching the given predicate is found. Return the presence stanza with annotations. waitForPresence :: (Presence -> Bool) -> Session -> IO Presence waitForPresence f s = fst <$> waitForPresenceA (f . fst) s diff --git a/source/Network/Xmpp/Concurrent/Types.hs b/source/Network/Xmpp/Concurrent/Types.hs index 415c1c4..360b9d9 100644 --- a/source/Network/Xmpp/Concurrent/Types.hs +++ b/source/Network/Xmpp/Concurrent/Types.hs @@ -139,22 +139,21 @@ type IQHandlers = ( Map.Map (IQRequestType, Text) (TChan IQRequestTicket) TMVar (Maybe (Annotated IQResponse))) ) --- | Contains whether or not a reply has been sent, and the IQ request body to --- reply to. +-- | A received and wrapped up IQ request. Prevents you from (illegally) +-- answering a single IQ request multiple times data IQRequestTicket = IQRequestTicket - { answerTicket :: Either StanzaError (Maybe Element) + { -- | Send an answer to an IQ request once. Subsequent calls will do + -- nothing and return Nothing + answerTicket :: Either StanzaError (Maybe Element) -> IO (Maybe (Either XmppFailure ())) - -- ^ Return Nothing when the IQ request was already - -- answered before, Just (Right ()) when it was - -- sucessfully answered and Just (Left error) when the - -- answer was attempted, but failed (e.g. there is a - -- connection failure) + -- | The actual IQ request that created this ticket. , iqRequestBody :: IQRequest -- | Annotations set by plugins in receive , iqRequestAnnotations :: [Annotation] } -- | Error that can occur during sendIQ' -data IQSendError = IQSendError XmppFailure -- There was an error sending the IQ stanza +data IQSendError = IQSendError XmppFailure -- There was an error sending the IQ + -- stanza | IQTimeOut -- No answer was received during the allotted time deriving (Show, Eq)