{-# OPTIONS_HADDOCK hide #-}
module Network.Xmpp.Concurrent.Message where

import Control.Applicative((<$>))
import Network.Xmpp.Concurrent.Types
import Control.Concurrent.STM
import Network.Xmpp.Types
import Network.Xmpp.Concurrent.Basic

-- | Draw and discard stanzas from the inbound channel until a message or
-- message error is found. Returns the message or message error with annotations.
pullMessageA :: Session -> IO (Either (Annotated MessageError) (Annotated Message))
pullMessageA :: Session -> IO (Either (Annotated MessageError) (Annotated Message))
pullMessageA Session
session = do
    (Stanza
stanza, [Annotation]
as) <- forall a. STM a -> IO a
atomically forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. TChan a -> STM a
readTChan forall a b. (a -> b) -> a -> b
$ Session -> TChan (Stanza, [Annotation])
stanzaCh Session
session
    case Stanza
stanza of
        MessageS Message
m      -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right (Message
m, [Annotation]
as)
        MessageErrorS MessageError
e -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left  (MessageError
e, [Annotation]
as)
        Stanza
_ -> Session -> IO (Either (Annotated MessageError) (Annotated Message))
pullMessageA Session
session

-- | Draw and discard stanzas from the inbound channel until a message or
-- message error is found. Returns the message or message error.
pullMessage :: Session -> IO (Either MessageError Message)
pullMessage :: Session -> IO (Either MessageError Message)
pullMessage Session
s = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) (forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Session -> IO (Either (Annotated MessageError) (Annotated Message))
pullMessageA Session
s

-- | Draw and discard stanzas from the inbound channel until a message is
-- found. Returns the message with annotations.
getMessageA :: Session -> IO (Annotated Message)
getMessageA :: Session -> IO (Annotated Message)
getMessageA = (Annotated Message -> Bool) -> Session -> IO (Annotated Message)
waitForMessageA (forall a b. a -> b -> a
const Bool
True)

-- | Draw and discard stanzas from the inbound channel until a message is
-- found. Returns the message.
getMessage :: Session -> IO Message
getMessage :: Session -> IO Message
getMessage Session
s = forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Session -> IO (Annotated Message)
getMessageA Session
s

-- | 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 :: (Annotated Message -> Bool) -> Session -> IO (Annotated Message)
waitForMessageA Annotated Message -> Bool
f Session
session = do
    Either (Annotated MessageError) (Annotated Message)
s <- Session -> IO (Either (Annotated MessageError) (Annotated Message))
pullMessageA Session
session
    case Either (Annotated MessageError) (Annotated Message)
s of
        Left Annotated MessageError
_ -> (Annotated Message -> Bool) -> Session -> IO (Annotated Message)
waitForMessageA Annotated Message -> Bool
f Session
session
        Right Annotated Message
m | Annotated Message -> Bool
f Annotated Message
m -> forall (m :: * -> *) a. Monad m => a -> m a
return Annotated Message
m
                | Bool
otherwise -> (Annotated Message -> Bool) -> Session -> IO (Annotated Message)
waitForMessageA Annotated Message -> Bool
f Session
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 :: (Message -> Bool) -> Session -> IO Message
waitForMessage Message -> Bool
f Session
s  = forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Annotated Message -> Bool) -> Session -> IO (Annotated Message)
waitForMessageA (Message -> Bool
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) Session
s

-- | 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)
waitForMessageErrorA :: (Annotated MessageError -> Bool)
-> Session -> IO (Annotated MessageError)
waitForMessageErrorA Annotated MessageError -> Bool
f Session
session = do
    Either (Annotated MessageError) (Annotated Message)
s <- Session -> IO (Either (Annotated MessageError) (Annotated Message))
pullMessageA Session
session
    case Either (Annotated MessageError) (Annotated Message)
s of
        Right Annotated Message
_ -> (Annotated MessageError -> Bool)
-> Session -> IO (Annotated MessageError)
waitForMessageErrorA Annotated MessageError -> Bool
f Session
session
        Left  Annotated MessageError
m | Annotated MessageError -> Bool
f Annotated MessageError
m -> forall (m :: * -> *) a. Monad m => a -> m a
return Annotated MessageError
m
                | Bool
otherwise -> (Annotated MessageError -> Bool)
-> Session -> IO (Annotated MessageError)
waitForMessageErrorA Annotated MessageError -> Bool
f Session
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 :: (MessageError -> Bool) -> Session -> IO MessageError
waitForMessageError MessageError -> Bool
f Session
s  = forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Annotated MessageError -> Bool)
-> Session -> IO (Annotated MessageError)
waitForMessageErrorA (MessageError -> Bool
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) Session
s

-- | 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)
                                        (Annotated Message))
filterMessagesA :: (Annotated MessageError -> Bool)
-> (Annotated Message -> Bool)
-> Session
-> IO (Either (Annotated MessageError) (Annotated Message))
filterMessagesA Annotated MessageError -> Bool
f Annotated Message -> Bool
g Session
session = do
    Either (Annotated MessageError) (Annotated Message)
s <- Session -> IO (Either (Annotated MessageError) (Annotated Message))
pullMessageA Session
session
    case Either (Annotated MessageError) (Annotated Message)
s of
        Left  Annotated MessageError
e | Annotated MessageError -> Bool
f Annotated MessageError
e -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left Annotated MessageError
e
                | Bool
otherwise -> (Annotated MessageError -> Bool)
-> (Annotated Message -> Bool)
-> Session
-> IO (Either (Annotated MessageError) (Annotated Message))
filterMessagesA Annotated MessageError -> Bool
f Annotated Message -> Bool
g Session
session
        Right Annotated Message
m | Annotated Message -> Bool
g Annotated Message
m -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right Annotated Message
m
                | Bool
otherwise -> (Annotated MessageError -> Bool)
-> (Annotated Message -> Bool)
-> Session
-> IO (Either (Annotated MessageError) (Annotated Message))
filterMessagesA Annotated MessageError -> Bool
f Annotated Message -> Bool
g Session
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
               -> IO (Either MessageError Message)
filterMessages :: (MessageError -> Bool)
-> (Message -> Bool) -> Session -> IO (Either MessageError Message)
filterMessages MessageError -> Bool
f Message -> Bool
g Session
s = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) (forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                          (Annotated MessageError -> Bool)
-> (Annotated Message -> Bool)
-> Session
-> IO (Either (Annotated MessageError) (Annotated Message))
filterMessagesA (MessageError -> Bool
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) (Message -> Bool
g forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) Session
s

-- | Send a message stanza. Returns @Left@ when the 'Message' could not be
-- sent.
sendMessage :: Message -> Session -> IO (Either XmppFailure ())
sendMessage :: Message -> Session -> IO (Either XmppFailure ())
sendMessage Message
m Session
session = Stanza -> Session -> IO (Either XmppFailure ())
sendStanza (Message -> Stanza
MessageS Message
m) Session
session