blob: 71957c4a8ec242e843326477def358962ed4e5bd [file] [log] [blame]
Bryan Duxburye59a80f2010-09-20 15:21:37 +00001{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE KindSignatures #-}
3{-# LANGUAGE RankNTypes #-}
David Reissea2cba82009-03-30 21:35:00 +00004--
5-- Licensed to the Apache Software Foundation (ASF) under one
6-- or more contributor license agreements. See the NOTICE file
7-- distributed with this work for additional information
8-- regarding copyright ownership. The ASF licenses this file
9-- to you under the Apache License, Version 2.0 (the
10-- "License"); you may not use this file except in compliance
11-- with the License. You may obtain a copy of the License at
12--
13-- http://www.apache.org/licenses/LICENSE-2.0
14--
15-- Unless required by applicable law or agreed to in writing,
16-- software distributed under the License is distributed on an
17-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18-- KIND, either express or implied. See the License for the
19-- specific language governing permissions and limitations
20-- under the License.
21--
22
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000023module Thrift
24 ( module Thrift.Transport
25 , module Thrift.Protocol
26 , AppExnType(..)
27 , AppExn(..)
28 , readAppExn
29 , writeAppExn
30 , ThriftException(..)
31 ) where
iproctorff8eb922007-07-25 19:06:13 +000032
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000033import Control.Monad ( when )
34import Control.Exception
iproctorff8eb922007-07-25 19:06:13 +000035
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000036import Data.Typeable ( Typeable )
iproctorff8eb922007-07-25 19:06:13 +000037
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000038import Thrift.Transport
39import Thrift.Protocol
David Reiss0c90f6f2008-02-06 22:18:40 +000040
41
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000042data ThriftException = ThriftException
43 deriving ( Show, Typeable )
44instance Exception ThriftException
David Reiss0c90f6f2008-02-06 22:18:40 +000045
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000046data AppExnType
47 = AE_UNKNOWN
48 | AE_UNKNOWN_METHOD
49 | AE_INVALID_MESSAGE_TYPE
50 | AE_WRONG_METHOD_NAME
51 | AE_BAD_SEQUENCE_ID
52 | AE_MISSING_RESULT
53 deriving ( Eq, Show, Typeable )
David Reiss0c90f6f2008-02-06 22:18:40 +000054
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000055instance Enum AppExnType where
56 toEnum 0 = AE_UNKNOWN
57 toEnum 1 = AE_UNKNOWN_METHOD
58 toEnum 2 = AE_INVALID_MESSAGE_TYPE
59 toEnum 3 = AE_WRONG_METHOD_NAME
60 toEnum 4 = AE_BAD_SEQUENCE_ID
61 toEnum 5 = AE_MISSING_RESULT
Bryan Duxburye59a80f2010-09-20 15:21:37 +000062 toEnum t = error $ "Invalid AppExnType " ++ show t
David Reiss0c90f6f2008-02-06 22:18:40 +000063
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000064 fromEnum AE_UNKNOWN = 0
65 fromEnum AE_UNKNOWN_METHOD = 1
66 fromEnum AE_INVALID_MESSAGE_TYPE = 2
67 fromEnum AE_WRONG_METHOD_NAME = 3
68 fromEnum AE_BAD_SEQUENCE_ID = 4
69 fromEnum AE_MISSING_RESULT = 5
David Reiss0c90f6f2008-02-06 22:18:40 +000070
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000071data AppExn = AppExn { ae_type :: AppExnType, ae_message :: String }
72 deriving ( Show, Typeable )
73instance Exception AppExn
David Reiss0c90f6f2008-02-06 22:18:40 +000074
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000075writeAppExn :: (Protocol p, Transport t) => p t -> AppExn -> IO ()
76writeAppExn pt ae = do
77 writeStructBegin pt "TApplicationException"
David Reiss0c90f6f2008-02-06 22:18:40 +000078
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000079 when (ae_message ae /= "") $ do
80 writeFieldBegin pt ("message", T_STRING , 1)
81 writeString pt (ae_message ae)
82 writeFieldEnd pt
David Reiss0c90f6f2008-02-06 22:18:40 +000083
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000084 writeFieldBegin pt ("type", T_I32, 2);
Bryan Duxbury75a33e82010-09-22 00:48:56 +000085 writeI32 pt (fromIntegral $ fromEnum (ae_type ae))
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000086 writeFieldEnd pt
87 writeFieldStop pt
88 writeStructEnd pt
David Reiss0c90f6f2008-02-06 22:18:40 +000089
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000090readAppExn :: (Protocol p, Transport t) => p t -> IO AppExn
91readAppExn pt = do
Bryan Duxburye59a80f2010-09-20 15:21:37 +000092 _ <- readStructBegin pt
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000093 rec <- readAppExnFields pt (AppExn {ae_type = undefined, ae_message = undefined})
94 readStructEnd pt
95 return rec
David Reiss0c90f6f2008-02-06 22:18:40 +000096
Bryan Duxburye59a80f2010-09-20 15:21:37 +000097readAppExnFields :: forall (a :: * -> *) t. (Protocol a, Transport t) => a t -> AppExn -> IO AppExn
Bryan Duxbury0781f2b2009-04-07 23:29:42 +000098readAppExnFields pt rec = do
Bryan Duxburye59a80f2010-09-20 15:21:37 +000099 (_, ft, tag) <- readFieldBegin pt
Bryan Duxbury0781f2b2009-04-07 23:29:42 +0000100 if ft == T_STOP
101 then return rec
Bryan Duxburye59a80f2010-09-20 15:21:37 +0000102 else case tag of
Bryan Duxbury0781f2b2009-04-07 23:29:42 +0000103 1 -> if ft == T_STRING then
104 do s <- readString pt
105 readAppExnFields pt rec{ae_message = s}
106 else do skip pt ft
107 readAppExnFields pt rec
108 2 -> if ft == T_I32 then
109 do i <- readI32 pt
Bryan Duxbury75a33e82010-09-22 00:48:56 +0000110 readAppExnFields pt rec{ae_type = (toEnum $ fromIntegral i)}
Bryan Duxbury0781f2b2009-04-07 23:29:42 +0000111 else do skip pt ft
112 readAppExnFields pt rec
113 _ -> do skip pt ft
114 readFieldEnd pt
115 readAppExnFields pt rec
David Reiss0c90f6f2008-02-06 22:18:40 +0000116