hackage-server-0.4: Distribution/Server/Framework/Instances.hs
{-# LANGUAGE DeriveDataTypeable, StandaloneDeriving, FlexibleContexts, CPP #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- | 'Typeable', 'Binary', 'Serialize', 'Text', and 'NFData' instances for various
-- types from Cabal, and other standard libraries.
--
-- Major version changes may break this module.
--
module Distribution.Server.Framework.Instances () where
import Distribution.Text
import Distribution.Server.Framework.MemSize
import Distribution.Package (PackageIdentifier(..), PackageName(..))
import Distribution.PackageDescription
(GenericPackageDescription(..))
import Distribution.Version (Version(..), VersionRange(..))
import Data.Typeable
import Data.Time.Clock (UTCTime(..))
import Data.Time.Calendar (Day(..))
import Control.DeepSeq
import qualified Data.Serialize as Serialize
import Data.Serialize (Serialize)
import Data.SafeCopy (SafeCopy(getCopy, putCopy), contain)
import Happstack.Server
import Data.Maybe (fromJust)
import qualified Text.PrettyPrint as PP (text)
import Distribution.Compat.ReadP (readS_to_P)
#if !(MIN_VERSION_bytestring(0,10,0))
import qualified Data.ByteString as SBS
import qualified Data.ByteString.Lazy as LBS
#endif
deriving instance Typeable PackageIdentifier
deriving instance Typeable GenericPackageDescription
deriving instance Typeable PackageName
deriving instance Typeable VersionRange
instance Serialize PackageIdentifier where
put = Serialize.put . show
get = fmap read Serialize.get
instance SafeCopy PackageIdentifier where
putCopy = contain . Serialize.put . show
getCopy = contain $ fmap read Serialize.get
instance SafeCopy PackageName where
getCopy = contain textGet
putCopy = contain . textPut
instance SafeCopy Version where
getCopy = contain textGet
putCopy = contain . textPut
instance SafeCopy VersionRange where
getCopy = contain textGet
putCopy = contain . textPut
instance FromReqURI PackageIdentifier where
fromReqURI = simpleParse
instance FromReqURI PackageName where
fromReqURI = simpleParse
instance FromReqURI Version where
fromReqURI = simpleParse
-- These assume that the text representations
-- for Cabal types will be stable over time
textGet :: Text a => Serialize.Get a
textGet = (fromJust . simpleParse) `fmap` Serialize.get
textPut :: Text a => a -> Serialize.Put
textPut = Serialize.put . display
instance Serialize UTCTime where
put time = do
Serialize.put (toModifiedJulianDay $ utctDay time)
Serialize.put (toRational $ utctDayTime time)
get = do
day <- Serialize.get
secs <- Serialize.get
return (UTCTime (ModifiedJulianDay day) (fromRational secs))
-- rough versions of RNF for these
#if !(MIN_VERSION_bytestring(0,10,0))
instance NFData LBS.ByteString where
rnf bs = LBS.length bs `seq` ()
instance NFData SBS.ByteString where
rnf bs = bs `seq` ()
#endif
instance NFData Response where
rnf res@(Response{}) = rnf (rsBody res) `seq` rnf (rsHeaders res)
rnf _ = ()
instance NFData HeaderPair where
rnf (HeaderPair a b) = rnf a `seq` rnf b
instance NFData PackageName where
rnf (PackageName pkg) = rnf pkg
instance NFData PackageIdentifier where
rnf (PackageIdentifier name version) = rnf name `seq` rnf version
#if !(MIN_VERSION_deepseq(1,3,0))
instance NFData Version where
rnf (Version branch tags) = rnf branch `seq` rnf tags
#endif
#if !(MIN_VERSION_time(1,4,0))
instance NFData Day where
rnf (ModifiedJulianDay a) = rnf a
#endif
instance MemSize Response where
memSize (Response a b c d e) = memSize5 a b c d e
memSize (SendFile{}) = 42
instance MemSize HeaderPair where
memSize (HeaderPair a b) = memSize2 a b
instance MemSize RsFlags where
memSize (RsFlags a) = memSize1 a
instance MemSize Length where
memSize _ = memSize0
instance Text Day where
disp = PP.text . show
parse = readS_to_P (reads :: ReadS Day)