Skip to content

Commit

Permalink
D.Compat.Binary: backport binary generics to binary-0.5
Browse files Browse the repository at this point in the history
GHC generics are used to derive binary instances for types appearing
in the persistent build config, which requires GHC >= 7.2 and
binary >= 0.7. Unfortunately, GHC < 7.8 ships with binary == 0.5.*.
The missing module is Data.Binary.Generics, which we have copied from
binary-0.7.2.3 to Distribution.Compat.Binary.Generics. To provide
generic implementations for the Binary class, we also have to provide
our own implementation, which is copied from binary-0.7.2.3 to
Distribution.Compat.Binary.Class. The interface required by Cabal is
exported from Distribution.Compat.Binary. This is only done if
bootstrapping Cabal with GHC < 7.8 or if binary >= 0.7 is not available,
otherwise Distribution.Compat.Binary simply re-exports Data.Binary.
  • Loading branch information
ttuegel committed Jan 8, 2015
1 parent 1fd5b35 commit c650e34
Show file tree
Hide file tree
Showing 23 changed files with 754 additions and 26 deletions.
18 changes: 15 additions & 3 deletions Cabal/Cabal.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,12 @@ source-repository head
location: https://github.com/haskell/cabal/
subdir: Cabal

flag bundled-binary-generic
default: False

library
build-depends:
base >= 4.4 && < 5,
binary >= 0.7 && < 0.8,
deepseq >= 1.3 && < 1.5,
filepath >= 1 && < 1.4,
directory >= 1 && < 1.3,
Expand All @@ -140,6 +142,11 @@ library
pretty >= 1 && < 1.2,
bytestring >= 0.9

if flag(bundled-binary-generic)
build-depends: binary >= 0.5 && < 0.7
else
build-depends: binary >= 0.7 && < 0.8

-- Needed for GHC.Generics before GHC 7.6
if impl(ghc < 7.6)
build-depends: ghc-prim >= 0.2 && < 0.3
Expand Down Expand Up @@ -225,6 +232,7 @@ library
Language.Haskell.Extension

other-modules:
Distribution.Compat.Binary
Distribution.Compat.CopyFile
Distribution.Compat.TempFile
Distribution.GetOpt
Expand All @@ -234,6 +242,11 @@ library
Distribution.Simple.GHC.ImplInfo
Paths_Cabal

if flag(bundled-binary-generic)
other-modules:
Distribution.Compat.Binary.Class
Distribution.Compat.Binary.Generic

default-language: Haskell98
default-extensions: CPP

Expand Down Expand Up @@ -294,7 +307,6 @@ test-suite package-tests
hs-source-dirs: tests
build-depends:
base,
binary >= 0.7 && < 0.8,
containers,
test-framework,
test-framework-quickcheck2 >= 0.2.12,
Expand All @@ -312,4 +324,4 @@ test-suite package-tests
build-depends: unix
ghc-options: -Wall
default-extensions: CPP
default-language: Haskell98
default-language: Haskell98
57 changes: 57 additions & 0 deletions Cabal/Distribution/Compat/Binary.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{-# LANGUAGE CPP #-}

#ifndef MIN_VERSION_binary
#define MIN_VERSION_binary(x, y, z) 0
#endif

module Distribution.Compat.Binary
( decodeOrFailIO
#if __GLASGOW_HASKELL__ >= 708 || MIN_VERSION_binary(0,7,0)
, module Data.Binary
#else
, Binary(..)
, decode, encode
#endif
) where

import Data.ByteString.Lazy (ByteString)

#if __GLASGOW_HASKELL__ >= 708 || MIN_VERSION_binary(0,7,0)

import Data.Binary

decodeOrFailIO :: Binary a => ByteString -> IO (Either String a)
decodeOrFailIO bs =
return $ case decodeOrFail bs of
Left (_, _, msg) -> Left msg
Right (_, _, a) -> Right a

#else

import Control.Exception (ErrorCall(..), catch, evaluate)
import Data.Binary.Get
import Data.Binary.Put
#if __GLASGOW_HASKELL__ < 706
import Prelude hiding (catch)
#endif

import Distribution.Compat.Binary.Class
import Distribution.Compat.Binary.Generic ()

-- | Decode a value from a lazy ByteString, reconstructing the original structure.
--
decode :: Binary a => ByteString -> a
decode = runGet get

-- | Encode a value using binary serialisation to a lazy ByteString.
--
encode :: Binary a => a -> ByteString
encode = runPut . put
{-# INLINE encode #-}

decodeOrFailIO :: Binary a => ByteString -> IO (Either String a)
decodeOrFailIO bs =
catch (evaluate (decode bs) >>= return . Right)
$ \(ErrorCall str) -> return $ Left str

#endif
Loading

0 comments on commit c650e34

Please sign in to comment.