{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
module Thrift
( module Thrift.Transport
, module Thrift.Protocol
, AppExnType(..)
, AppExn(..)
, readAppExn
, writeAppExn
, ThriftException(..)
) where
import Control.Exception
import Data.Int
import Data.Text.Lazy ( Text, pack, unpack )
import Data.Text.Lazy.Encoding
import Data.Typeable ( Typeable )
import qualified Data.HashMap.Strict as Map
import Thrift.Protocol
import Thrift.Transport
import Thrift.Types
data ThriftException = ThriftException
deriving ( Show, Typeable )
instance Exception ThriftException
data AppExnType
= AE_UNKNOWN
| AE_UNKNOWN_METHOD
| AE_INVALID_MESSAGE_TYPE
| AE_WRONG_METHOD_NAME
| AE_BAD_SEQUENCE_ID
| AE_MISSING_RESULT
| AE_INTERNAL_ERROR
| AE_PROTOCOL_ERROR
| AE_INVALID_TRANSFORM
| AE_INVALID_PROTOCOL
| AE_UNSUPPORTED_CLIENT_TYPE
deriving ( Eq, Show, Typeable )
instance Enum AppExnType where
toEnum 0 = AE_UNKNOWN
toEnum 1 = AE_UNKNOWN_METHOD
toEnum 2 = AE_INVALID_MESSAGE_TYPE
toEnum 3 = AE_WRONG_METHOD_NAME
toEnum 4 = AE_BAD_SEQUENCE_ID
toEnum 5 = AE_MISSING_RESULT
toEnum 6 = AE_INTERNAL_ERROR
toEnum 7 = AE_PROTOCOL_ERROR
toEnum 8 = AE_INVALID_TRANSFORM
toEnum 9 = AE_INVALID_PROTOCOL
toEnum 10 = AE_UNSUPPORTED_CLIENT_TYPE
toEnum t = error $ "Invalid AppExnType " ++ show t
fromEnum AE_UNKNOWN = 0
fromEnum AE_UNKNOWN_METHOD = 1
fromEnum AE_INVALID_MESSAGE_TYPE = 2
fromEnum AE_WRONG_METHOD_NAME = 3
fromEnum AE_BAD_SEQUENCE_ID = 4
fromEnum AE_MISSING_RESULT = 5
fromEnum AE_INTERNAL_ERROR = 6
fromEnum AE_PROTOCOL_ERROR = 7
fromEnum AE_INVALID_TRANSFORM = 8
fromEnum AE_INVALID_PROTOCOL = 9
fromEnum AE_UNSUPPORTED_CLIENT_TYPE = 10
data AppExn = AppExn { ae_type :: AppExnType, ae_message :: String }
deriving ( Show, Typeable )
instance Exception AppExn
writeAppExn :: Protocol p => p -> AppExn -> IO ()
writeAppExn pt ae = writeVal pt $ TStruct $ Map.fromList
[ (1, ("message", TString $ encodeUtf8 $ pack $ ae_message ae))
, (2, ("type", TI32 $ fromIntegral $ fromEnum (ae_type ae)))
]
readAppExn :: Protocol p => p -> IO AppExn
readAppExn pt = do
let typemap = Map.fromList [(1,("message",T_STRING)),(2,("type",T_I32))]
TStruct fields <- readVal pt $ T_STRUCT typemap
return $ readAppExnFields fields
readAppExnFields :: Map.HashMap Int16 (Text, ThriftVal) -> AppExn
readAppExnFields fields = AppExn{
ae_message = maybe undefined unwrapMessage $ Map.lookup 1 fields,
ae_type = maybe undefined unwrapType $ Map.lookup 2 fields
}
where
unwrapMessage (_, TString s) = unpack $ decodeUtf8 s
unwrapMessage _ = undefined
unwrapType (_, TI32 i) = toEnum $ fromIntegral i
unwrapType _ = undefined