{-# LANGUAGE CPP #-}

module Nix.Cache where

import qualified Data.ByteString.Lazy          as BS
import           Nix.Expr.Types.Annotated

#if defined (__linux__)
#define USE_COMPACT 1
#endif

#ifdef USE_COMPACT
import qualified Data.Compact as C
import qualified Data.Compact.Serialize as C
#endif
#ifdef MIN_VERSION_serialise
import qualified Codec.Serialise               as S
#endif

readCache :: FilePath -> IO NExprLoc
readCache :: FilePath -> IO NExprLoc
readCache path :: FilePath
path = do
#if USE_COMPACT
    eres <- C.unsafeReadCompact path
    case eres of
        Left err -> error $ "Error reading cache file: " ++ err
        Right expr -> return $ C.getCompact expr
#else
#ifdef MIN_VERSION_serialise
  Either DeserialiseFailure NExprLoc
eres <- ByteString -> Either DeserialiseFailure NExprLoc
forall a. Serialise a => ByteString -> Either DeserialiseFailure a
S.deserialiseOrFail (ByteString -> Either DeserialiseFailure NExprLoc)
-> IO ByteString -> IO (Either DeserialiseFailure NExprLoc)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO ByteString
BS.readFile FilePath
path
  case Either DeserialiseFailure NExprLoc
eres of
    Left  err :: DeserialiseFailure
err  -> FilePath -> IO NExprLoc
forall a. HasCallStack => FilePath -> a
error (FilePath -> IO NExprLoc) -> FilePath -> IO NExprLoc
forall a b. (a -> b) -> a -> b
$ "Error reading cache file: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ DeserialiseFailure -> FilePath
forall a. Show a => a -> FilePath
show DeserialiseFailure
err
    Right expr :: NExprLoc
expr -> NExprLoc -> IO NExprLoc
forall (m :: * -> *) a. Monad m => a -> m a
return NExprLoc
expr
#else
    error "readCache not implemented for this platform"
#endif
#endif

writeCache :: FilePath -> NExprLoc -> IO ()
writeCache :: FilePath -> NExprLoc -> IO ()
writeCache path :: FilePath
path expr :: NExprLoc
expr =
#ifdef USE_COMPACT
    C.writeCompact path =<< C.compact expr
#else
#ifdef MIN_VERSION_serialise
  FilePath -> ByteString -> IO ()
BS.writeFile FilePath
path (NExprLoc -> ByteString
forall a. Serialise a => a -> ByteString
S.serialise NExprLoc
expr)
#else
    error "writeCache not implemented for this platform"
#endif
#endif