module Network.BERT.Client
( Call, call
) where
import Data.BERT (Term(..), Packet(..), BERT(..))
import Network.BERT.Transport (Transport, withTransport, sendt, recvt)
data Error
= ClientError String
| ServerError Term
deriving (Show, Ord, Eq)
type Call a = IO (Either Error a)
call :: (BERT a, BERT b)
=> Transport
-> String
-> String
-> [a]
-> Call b
call transport mod fun args =
withTransport transport $ do
sendt $ TupleTerm [AtomTerm "call", AtomTerm mod, AtomTerm fun,
ListTerm $ map showBERT args]
recvt >>= handle
where
handle (TupleTerm [AtomTerm "reply", reply]) =
return $ either (const . Left $ ClientError "decode failed") Right
$ readBERT reply
handle (TupleTerm (AtomTerm "info":_)) =
recvt >>= handle
handle t@(TupleTerm (AtomTerm "error":_)) =
return $ Left . ServerError $ t
handle t = fail $ "unknown reply " ++ (show t)