{-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP #-} -- For PackageDescription and friends {-# OPTIONS_GHC -fno-warn-orphans #-} -- For encodeCtrN/decodeCtrBodyN/etc {-# OPTIONS_GHC -fno-warn-missing-signatures #-} module Macro.CBOR (serialise, deserialise, deserialiseNull) where import Macro.Types import Codec.Serialise.Class import Codec.Serialise.Encoding hiding (Tokens(..)) import Codec.Serialise.Decoding hiding (DecodeAction(Done, Fail)) import Codec.CBOR.Read import Codec.CBOR.Write #if ! MIN_VERSION_base(4,11,0) import Data.Monoid #endif import qualified Data.ByteString.Lazy as BS import qualified Data.ByteString.Builder as BS import Control.Exception (throw) #if !MIN_VERSION_base(4,8,0) import Control.Applicative import Data.Word #endif serialise :: [GenericPackageDescription] -> BS.ByteString --serialise :: Serialise a => a -> BS.ByteString serialise = BS.toLazyByteString . toBuilder . encode deserialise :: BS.ByteString -> [GenericPackageDescription] deserialise = either throw snd . deserialiseFromBytes decode deserialiseNull :: BS.ByteString -> () deserialiseNull = either throw snd . deserialiseFromBytes decodeListNull where decodeListNull :: Decoder s () decodeListNull = do decodeListLenIndef; go go = do stop <- decodeBreakOr if stop then return () else do !_ <- decode :: Decoder s GenericPackageDescription go encodeCtr0 n = encodeListLen 1 <> encode (n :: Word) encodeCtr1 n a = encodeListLen 2 <> encode (n :: Word) <> encode a encodeCtr2 n a b = encodeListLen 3 <> encode (n :: Word) <> encode a <> encode b encodeCtr3 n a b c = encodeListLen 4 <> encode (n :: Word) <> encode a <> encode b <> encode c encodeCtr4 n a b c d = encodeListLen 5 <> encode (n :: Word) <> encode a <> encode b <> encode c <> encode d encodeCtr6 n a b c d e f = encodeListLen 7 <> encode (n :: Word) <> encode a <> encode b <> encode c <> encode d <> encode e <> encode f encodeCtr7 n a b c d e f g = encodeListLen 8 <> encode (n :: Word) <> encode a <> encode b <> encode c <> encode d <> encode e <> encode f <> encode g {-# INLINE encodeCtr0 #-} {-# INLINE encodeCtr1 #-} {-# INLINE encodeCtr2 #-} {-# INLINE encodeCtr3 #-} {-# INLINE encodeCtr4 #-} {-# INLINE encodeCtr6 #-} {-# INLINE encodeCtr7 #-} {-# INLINE decodeCtrTag #-} {-# INLINE decodeCtrBody0 #-} {-# INLINE decodeCtrBody1 #-} {-# INLINE decodeCtrBody2 #-} decodeCtrTag = (\len tag -> (tag, len)) <$> decodeListLen <*> decodeWord decodeCtrBody0 1 f = pure f decodeCtrBody0 x _ = error $ "decodeCtrBody0: impossible tag " ++ show x decodeCtrBody1 2 f = do x1 <- decode return $! f x1 decodeCtrBody1 x _ = error $ "decodeCtrBody1: impossible tag " ++ show x decodeCtrBody2 3 f = do x1 <- decode x2 <- decode return $! f x1 x2 decodeCtrBody2 x _ = error $ "decodeCtrBody2: impossible tag " ++ show x {-# INLINE decodeSingleCtr1 #-} {-# INLINE decodeSingleCtr2 #-} {-# INLINE decodeSingleCtr3 #-} {-# INLINE decodeSingleCtr4 #-} {-# INLINE decodeSingleCtr6 #-} {-# INLINE decodeSingleCtr7 #-} decodeSingleCtr1 v f = decodeListLenOf 2 *> decodeWordOf v *> pure f <*> decode decodeSingleCtr2 v f = decodeListLenOf 3 *> decodeWordOf v *> pure f <*> decode <*> decode decodeSingleCtr3 v f = decodeListLenOf 4 *> decodeWordOf v *> pure f <*> decode <*> decode <*> decode decodeSingleCtr4 v f = decodeListLenOf 5 *> decodeWordOf v *> pure f <*> decode <*> decode <*> decode <*> decode decodeSingleCtr6 v f = decodeListLenOf 7 *> decodeWordOf v *> pure f <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode decodeSingleCtr7 v f = decodeListLenOf 8 *> decodeWordOf v *> pure f <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode instance Serialise PackageName where encode (PackageName a) = encodeCtr1 1 a decode = decodeSingleCtr1 1 PackageName instance Serialise Version where encode (Version a b) = encodeCtr2 1 a b decode = decodeSingleCtr2 1 Version instance Serialise PackageId where encode (PackageId a b) = encodeCtr2 1 a b decode = decodeSingleCtr2 1 PackageId instance Serialise VersionRange where encode AnyVersion = encodeCtr0 1 encode (ThisVersion a) = encodeCtr1 2 a encode (LaterVersion a) = encodeCtr1 3 a encode (EarlierVersion a) = encodeCtr1 4 a encode (WildcardVersion a) = encodeCtr1 5 a encode (UnionVersionRanges a b) = encodeCtr2 6 a b encode (IntersectVersionRanges a b) = encodeCtr2 7 a b encode (VersionRangeParens a) = encodeCtr1 8 a decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody0 l AnyVersion 2 -> decodeCtrBody1 l ThisVersion 3 -> decodeCtrBody1 l LaterVersion 4 -> decodeCtrBody1 l EarlierVersion 5 -> decodeCtrBody1 l WildcardVersion 6 -> decodeCtrBody2 l UnionVersionRanges 7 -> decodeCtrBody2 l IntersectVersionRanges 8 -> decodeCtrBody1 l VersionRangeParens x -> error $ "Serialise VersionRange: decode: impossible tag " ++ show x instance Serialise Dependency where encode (Dependency a b) = encodeCtr2 1 a b decode = decodeSingleCtr2 1 Dependency instance Serialise CompilerFlavor where encode GHC = encodeCtr0 1 encode NHC = encodeCtr0 2 encode YHC = encodeCtr0 3 encode Hugs = encodeCtr0 4 encode HBC = encodeCtr0 5 encode Helium = encodeCtr0 6 encode JHC = encodeCtr0 7 encode LHC = encodeCtr0 8 encode UHC = encodeCtr0 9 encode (HaskellSuite a) = encodeCtr1 10 a encode (OtherCompiler a) = encodeCtr1 11 a decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody0 l GHC 2 -> decodeCtrBody0 l NHC 3 -> decodeCtrBody0 l YHC 4 -> decodeCtrBody0 l Hugs 5 -> decodeCtrBody0 l HBC 6 -> decodeCtrBody0 l Helium 7 -> decodeCtrBody0 l JHC 8 -> decodeCtrBody0 l LHC 9 -> decodeCtrBody0 l UHC 10 -> decodeCtrBody1 l HaskellSuite 11 -> decodeCtrBody1 l OtherCompiler x -> error $ "Serialise CompilerFlavor: decode: impossible tag " ++ show x instance Serialise License where encode (GPL a) = encodeCtr1 1 a encode (AGPL a) = encodeCtr1 2 a encode (LGPL a) = encodeCtr1 3 a encode BSD3 = encodeCtr0 4 encode BSD4 = encodeCtr0 5 encode MIT = encodeCtr0 6 encode (Apache a) = encodeCtr1 7 a encode PublicDomain = encodeCtr0 8 encode AllRightsReserved = encodeCtr0 9 encode OtherLicense = encodeCtr0 10 encode (UnknownLicense a) = encodeCtr1 11 a decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody1 l GPL 2 -> decodeCtrBody1 l AGPL 3 -> decodeCtrBody1 l LGPL 4 -> decodeCtrBody0 l BSD3 5 -> decodeCtrBody0 l BSD4 6 -> decodeCtrBody0 l MIT 7 -> decodeCtrBody1 l Apache 8 -> decodeCtrBody0 l PublicDomain 9 -> decodeCtrBody0 l AllRightsReserved 10 -> decodeCtrBody0 l OtherLicense 11 -> decodeCtrBody1 l UnknownLicense x -> error $ "Serialise License: decode: impossible tag " ++ show x instance Serialise SourceRepo where encode (SourceRepo a b c d e f g) = encodeCtr7 1 a b c d e f g decode = decodeSingleCtr7 1 SourceRepo instance Serialise RepoKind where encode RepoHead = encodeCtr0 1 encode RepoThis = encodeCtr0 2 encode (RepoKindUnknown a) = encodeCtr1 3 a decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody0 l RepoHead 2 -> decodeCtrBody0 l RepoThis 3 -> decodeCtrBody1 l RepoKindUnknown x -> error $ "Serialise RepoKind: decode: impossible tag " ++ show x instance Serialise RepoType where encode Darcs = encodeCtr0 1 encode Git = encodeCtr0 2 encode SVN = encodeCtr0 3 encode CVS = encodeCtr0 4 encode Mercurial = encodeCtr0 5 encode GnuArch = encodeCtr0 6 encode Bazaar = encodeCtr0 7 encode Monotone = encodeCtr0 8 encode (OtherRepoType a) = encodeCtr1 9 a decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody0 l Darcs 2 -> decodeCtrBody0 l Git 3 -> decodeCtrBody0 l SVN 4 -> decodeCtrBody0 l CVS 5 -> decodeCtrBody0 l Mercurial 6 -> decodeCtrBody0 l GnuArch 7 -> decodeCtrBody0 l Bazaar 8 -> decodeCtrBody0 l Monotone 9 -> decodeCtrBody1 l OtherRepoType x -> error $ "Serialise RepoType: decode: impossible tag " ++ show x instance Serialise BuildType where encode Simple = encodeCtr0 1 encode Configure = encodeCtr0 2 encode Make = encodeCtr0 3 encode Custom = encodeCtr0 4 encode (UnknownBuildType a) = encodeCtr1 5 a decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody0 l Simple 2 -> decodeCtrBody0 l Configure 3 -> decodeCtrBody0 l Make 4 -> decodeCtrBody0 l Custom 5 -> decodeCtrBody1 l UnknownBuildType x -> error $ "Serialise BuildType: decode: impossible tag " ++ show x instance Serialise Library where encode (Library a b c) = encodeCtr3 1 a b c decode = decodeSingleCtr3 1 Library instance Serialise Executable where encode (Executable a b c) = encodeCtr3 1 a b c decode = decodeSingleCtr3 1 Executable instance Serialise TestSuite where encode (TestSuite a b c d) = encodeCtr4 1 a b c d decode = decodeSingleCtr4 1 TestSuite instance Serialise TestSuiteInterface where encode (TestSuiteExeV10 a b) = encodeCtr2 1 a b encode (TestSuiteLibV09 a b) = encodeCtr2 2 a b encode (TestSuiteUnsupported a) = encodeCtr1 3 a decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody2 l TestSuiteExeV10 2 -> decodeCtrBody2 l TestSuiteLibV09 3 -> decodeCtrBody1 l TestSuiteUnsupported x -> error $ "Serialise TestSuiteInterface: decode: impossible tag " ++ show x instance Serialise TestType where encode (TestTypeExe a) = encodeCtr1 1 a encode (TestTypeLib a) = encodeCtr1 2 a encode (TestTypeUnknown a b) = encodeCtr2 3 a b decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody1 l TestTypeExe 2 -> decodeCtrBody1 l TestTypeLib 3 -> decodeCtrBody2 l TestTypeUnknown x -> error $ "Serialise TestType: decode: impossible tag " ++ show x instance Serialise Benchmark where encode (Benchmark a b c d) = encodeCtr4 1 a b c d decode = decodeSingleCtr4 1 Benchmark instance Serialise BenchmarkInterface where encode (BenchmarkExeV10 a b) = encodeCtr2 1 a b encode (BenchmarkUnsupported a) = encodeCtr1 2 a decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody2 l BenchmarkExeV10 2 -> decodeCtrBody1 l BenchmarkUnsupported x -> error $ "Serialise BenchmarkInterface: decode: impossible tag " ++ show x instance Serialise BenchmarkType where encode (BenchmarkTypeExe a) = encodeCtr1 1 a encode (BenchmarkTypeUnknown a b) = encodeCtr2 2 a b decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody1 l BenchmarkTypeExe 2 -> decodeCtrBody2 l BenchmarkTypeUnknown x -> error $ "Serialise BenchmarkType: decode: impossible tag " ++ show x instance Serialise ModuleName where encode (ModuleName a) = encodeCtr1 1 a decode = decodeSingleCtr1 1 ModuleName instance Serialise BuildInfo where encode (BuildInfo a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25) = encodeListLen 26 <> encode (1 :: Word) <> encode a1 <> encode a2 <> encode a3 <> encode a4 <> encode a5 <> encode a6 <> encode a7 <> encode a8 <> encode a9 <> encode a10 <> encode a11 <> encode a12 <> encode a13 <> encode a14 <> encode a15 <> encode a16 <> encode a17 <> encode a18 <> encode a19 <> encode a20 <> encode a21 <> encode a22 <> encode a23 <> encode a24 <> encode a25 decode = decodeListLenOf 26 *> decodeWordOf 1 *> pure BuildInfo <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode instance Serialise Language where encode Haskell98 = encodeCtr0 1 encode Haskell2010 = encodeCtr0 2 encode (UnknownLanguage a) = encodeCtr1 3 a decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody0 l Haskell98 2 -> decodeCtrBody0 l Haskell2010 3 -> decodeCtrBody1 l UnknownLanguage x -> error $ "Serialise Language: decode: impossible tag " ++ show x instance Serialise Extension where encode (EnableExtension a) = encodeCtr1 1 a encode (DisableExtension a) = encodeCtr1 2 a encode (UnknownExtension a) = encodeCtr1 3 a decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody1 l EnableExtension 2 -> decodeCtrBody1 l DisableExtension 3 -> decodeCtrBody1 l UnknownExtension x -> error $ "Serialise Extension: decode: impossible tag " ++ show x instance Serialise KnownExtension where encode ke = encodeCtr1 1 (fromEnum ke) decode = decodeSingleCtr1 1 toEnum instance Serialise PackageDescription where encode (PackageDescription a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25 a26 a27 a28) = encodeListLen 29 <> encode (1 :: Word) <> encode a1 <> encode a2 <> encode a3 <> encode a4 <> encode a5 <> encode a6 <> encode a7 <> encode a8 <> encode a9 <> encode a10 <> encode a11 <> encode a12 <> encode a13 <> encode a14 <> encode a15 <> encode a16 <> encode a17 <> encode a18 <> encode a19 <> encode a20 <> encode a21 <> encode a22 <> encode a23 <> encode a24 <> encode a25 <> encode a26 <> encode a27 <> encode a28 decode = decodeListLenOf 29 *> decodeWordOf 1 *> pure PackageDescription <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode <*> decode instance Serialise OS where encode Linux = encodeCtr0 1 encode Windows = encodeCtr0 2 encode OSX = encodeCtr0 3 encode FreeBSD = encodeCtr0 4 encode OpenBSD = encodeCtr0 5 encode NetBSD = encodeCtr0 6 encode Solaris = encodeCtr0 7 encode AIX = encodeCtr0 8 encode HPUX = encodeCtr0 9 encode IRIX = encodeCtr0 10 encode HaLVM = encodeCtr0 11 encode IOS = encodeCtr0 12 encode (OtherOS a) = encodeCtr1 13 a decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody0 l Linux 2 -> decodeCtrBody0 l Windows 3 -> decodeCtrBody0 l OSX 4 -> decodeCtrBody0 l FreeBSD 5 -> decodeCtrBody0 l OpenBSD 6 -> decodeCtrBody0 l NetBSD 7 -> decodeCtrBody0 l Solaris 8 -> decodeCtrBody0 l AIX 9 -> decodeCtrBody0 l HPUX 10 -> decodeCtrBody0 l IRIX 11 -> decodeCtrBody0 l HaLVM 12 -> decodeCtrBody0 l IOS 13 -> decodeCtrBody1 l OtherOS x -> error $ "Serialise OS: decode: impossible tag " ++ show x instance Serialise Arch where encode I386 = encodeCtr0 1 encode X86_64 = encodeCtr0 2 encode PPC = encodeCtr0 3 encode PPC64 = encodeCtr0 4 encode Sparc = encodeCtr0 5 encode Arm = encodeCtr0 6 encode Mips = encodeCtr0 7 encode SH = encodeCtr0 8 encode IA64 = encodeCtr0 9 encode S390 = encodeCtr0 10 encode Alpha = encodeCtr0 11 encode Hppa = encodeCtr0 12 encode Rs6000 = encodeCtr0 13 encode M68k = encodeCtr0 14 encode (OtherArch a) = encodeCtr1 15 a encode Vax = encodeCtr0 16 decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody0 l I386 2 -> decodeCtrBody0 l X86_64 3 -> decodeCtrBody0 l PPC 4 -> decodeCtrBody0 l PPC64 5 -> decodeCtrBody0 l Sparc 6 -> decodeCtrBody0 l Arm 7 -> decodeCtrBody0 l Mips 8 -> decodeCtrBody0 l SH 9 -> decodeCtrBody0 l IA64 10 -> decodeCtrBody0 l S390 11 -> decodeCtrBody0 l Alpha 12 -> decodeCtrBody0 l Hppa 13 -> decodeCtrBody0 l Rs6000 14 -> decodeCtrBody0 l M68k 15 -> decodeCtrBody1 l OtherArch 16 -> decodeCtrBody0 l Vax x -> error $ "Serialise Arch: decode: impossible tag " ++ show x instance Serialise Flag where encode (MkFlag a b c d) = encodeCtr4 1 a b c d decode = decodeSingleCtr4 1 MkFlag instance Serialise FlagName where encode (FlagName a) = encodeCtr1 1 a decode = decodeSingleCtr1 1 FlagName instance (Serialise a, Serialise b, Serialise c) => Serialise (CondTree a b c) where encode (CondNode a b c) = encodeCtr3 1 a b c decode = decodeSingleCtr3 1 CondNode {-# SPECIALIZE instance Serialise c => Serialise (CondTree ConfVar [Dependency] c) #-} instance Serialise ConfVar where encode (OS a) = encodeCtr1 1 a encode (Arch a) = encodeCtr1 2 a encode (Flag a) = encodeCtr1 3 a encode (Impl a b) = encodeCtr2 4 a b decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody1 l OS 2 -> decodeCtrBody1 l Arch 3 -> decodeCtrBody1 l Flag 4 -> decodeCtrBody2 l Impl x -> error $ "Serialise ConfVar: decode: impossible tag " ++ show x instance Serialise a => Serialise (Condition a) where encode (Var a) = encodeCtr1 1 a encode (Lit a) = encodeCtr1 2 a encode (CNot a) = encodeCtr1 3 a encode (COr a b) = encodeCtr2 4 a b encode (CAnd a b) = encodeCtr2 5 a b decode = do (t,l) <- decodeCtrTag case t of 1 -> decodeCtrBody1 l Var 2 -> decodeCtrBody1 l Lit 3 -> decodeCtrBody1 l CNot 4 -> decodeCtrBody2 l COr 5 -> decodeCtrBody2 l CAnd x -> error $ "Serialise (Condition a): decode: impossible tag " ++ show x {-# SPECIALIZE instance Serialise (Condition ConfVar) #-} instance Serialise GenericPackageDescription where encode (GenericPackageDescription a b c d e f) = encodeCtr6 1 a b c d e f decode = decodeSingleCtr6 1 GenericPackageDescription