fluent-logger-0.2.3.1: test/Network/Fluent/Logger/Unpackable.hs
{-# LANGUAGE FlexibleInstances, IncoherentInstances, TypeSynonymInstances #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE CPP #-}
-- | For compatibility with msgpack
module Network.Fluent.Logger.Unpackable where
import Control.Exception
import Data.Typeable
import Data.MessagePack
import qualified Data.Map as M
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
#if MIN_VERSION_messagepack(0,4,0)
import qualified Data.Text.Encoding as T
import qualified Data.Text.Lazy.Encoding as LT
#endif
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy as LBS
data UnpackError =
UnpackError String
deriving (Show, Typeable)
instance Exception UnpackError
-- | Deserializable Type
--
-- Since 0.2.0.0
--
class Unpackable a where
unpack :: Object -> a
instance Unpackable Object where
unpack = id
instance Unpackable () where
unpack ObjectNil = ()
unpack x = throw $ UnpackError $ "invalid for nil: " ++ show x
instance Unpackable Int where
unpack (ObjectInt x) = fromIntegral x
unpack x = throw $ UnpackError $ "invalid for int: " ++ show x
instance Unpackable String where
#if MIN_VERSION_messagepack(0,4,0)
unpack (ObjectString x) = BS.unpack x
#else
unpack (ObjectString x) = T.unpack x
#endif
unpack x = throw $ UnpackError $ "invalid for string: " ++ show x
instance Unpackable BS.ByteString where
unpack (ObjectBinary x) = x
unpack x = throw $ UnpackError $ "invalid for binary: " ++ show x
instance Unpackable LBS.ByteString where
unpack (ObjectBinary x) = LBS.fromStrict x
unpack x = throw $ UnpackError $ "invalid for binary: " ++ show x
instance Unpackable T.Text where
#if MIN_VERSION_messagepack(0,4,0)
unpack (ObjectString x) = T.decodeUtf8 x
#else
unpack (ObjectString x) = x
#endif
unpack x = throw $ UnpackError $ "invalid for string: " ++ show x
instance Unpackable LT.Text where
#if MIN_VERSION_messagepack(0,4,0)
unpack x@(ObjectString _) = LT.decodeUtf8 . unpack $ x
#else
unpack (ObjectString x) = LT.pack . T.unpack $ x
#endif
unpack x = throw $ UnpackError $ "invalid for string: " ++ show x
instance (Unpackable a1, Unpackable a2) => Unpackable (a1, a2) where
unpack (ObjectArray (a1:a2:[])) = (unpack a1, unpack a2)
unpack x = throw $ UnpackError $ "invalid for array: " ++ show x
instance (Unpackable a1, Unpackable a2, Unpackable a3) => Unpackable (a1, a2, a3) where
unpack (ObjectArray (a1:a2:a3:[])) = (unpack a1, unpack a2, unpack a3)
unpack x = throw $ UnpackError $ "invalid for array: " ++ show x
instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4) => Unpackable (a1, a2, a3, a4) where
unpack (ObjectArray (a1:a2:a3:a4:[])) = (unpack a1, unpack a2, unpack a3, unpack a4)
unpack x = throw $ UnpackError $ "invalid for array: " ++ show x
instance (Unpackable a1, Unpackable a2, Unpackable a3, Unpackable a4, Unpackable a5) => Unpackable (a1, a2, a3, a4, a5) where
unpack (ObjectArray (a1:a2:a3:a4:a5:[])) = (unpack a1, unpack a2, unpack a3, unpack a4, unpack a5)
unpack x = throw $ UnpackError $ "invalid for array: " ++ show x
instance (Ord k, Unpackable k, Unpackable v) => Unpackable (M.Map k v) where
unpack (ObjectMap x) = M.foldWithKey (\k v -> M.insert (unpack k) (unpack v)) M.empty x
unpack x = throw $ UnpackError $ "invalid for map: " ++ show x