From 48674a62c7d1fb9932c2bd234e6f851ec75478ac Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 29 Jul 2014 14:53:17 -0400 Subject: add ContentSource type, for remotes that act on files rather than ByteStrings Note that currently nothing cleans up a ContentSource's file, when eg, retrieving chunks. --- Types/StoreRetrieve.hs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Types/StoreRetrieve.hs (limited to 'Types') diff --git a/Types/StoreRetrieve.hs b/Types/StoreRetrieve.hs new file mode 100644 index 000000000..2520d6309 --- /dev/null +++ b/Types/StoreRetrieve.hs @@ -0,0 +1,54 @@ +{- Types for Storer and Retriever + - + - Copyright 2014 Joey Hess + - + - Licensed under the GNU GPL version 3 or higher. + -} + +{-# LANGUAGE Rank2Types #-} + +module Types.StoreRetrieve where + +import Common.Annex +import Utility.Metered +import Utility.Tmp + +import qualified Data.ByteString.Lazy as L + +-- Prepares for and then runs an action that will act on a Key's +-- content, passing it a helper when the preparation is successful. +type Preparer helper = forall a. Key -> (Maybe helper -> Annex a) -> Annex a + +-- A source of a Key's content. +data ContentSource + = FileContent FilePath + | ByteContent L.ByteString + +-- Action that stores a Key's content on a remote. +-- Can throw exceptions. +type Storer = Key -> ContentSource -> MeterUpdate -> IO Bool + +-- Action that retrieves a Key's content from a remote. +-- Throws exception if key is not present, or remote is not accessible. +type Retriever = Key -> IO ContentSource + +fileStorer :: (Key -> FilePath -> MeterUpdate -> IO Bool) -> Storer +fileStorer a k (FileContent f) m = a k f m +fileStorer a k (ByteContent b) m = do + withTmpFile "tmpXXXXXX" $ \f h -> do + L.hPut h b + hClose h + a k f m + +byteStorer :: (Key -> L.ByteString -> MeterUpdate -> IO Bool) -> Storer +byteStorer a k c m = withBytes c $ \b -> a k b m + +withBytes :: ContentSource -> (L.ByteString -> IO a) -> IO a +withBytes (ByteContent b) a = a b +withBytes (FileContent f) a = a =<< L.readFile f + +fileRetriever :: (Key -> IO FilePath) -> Retriever +fileRetriever a k = FileContent <$> a k + +byteRetriever :: (Key -> IO L.ByteString) -> Retriever +byteRetriever a k = ByteContent <$> a k -- cgit v1.2.3