diff options
Diffstat (limited to 'src/Hakyll/Core/Compiler')
-rw-r--r-- | src/Hakyll/Core/Compiler/Internal.hs | 33 | ||||
-rw-r--r-- | src/Hakyll/Core/Compiler/Require.hs | 63 |
2 files changed, 85 insertions, 11 deletions
diff --git a/src/Hakyll/Core/Compiler/Internal.hs b/src/Hakyll/Core/Compiler/Internal.hs index f211367..5b7fb51 100644 --- a/src/Hakyll/Core/Compiler/Internal.hs +++ b/src/Hakyll/Core/Compiler/Internal.hs @@ -5,19 +5,21 @@ module Hakyll.Core.Compiler.Internal ( CompilerRead (..) , CompilerResult (..) - , Compiler + , Compiler (..) , runCompiler , compilerTell , compilerAsk , compilerThrow , compilerCatch , compilerResult + , compilerUnsafeIO ) where -------------------------------------------------------------------------------- import Control.Applicative (Alternative (..), Applicative (..)) +import Control.Exception (SomeException, handle) import Data.Monoid (mappend, mempty) @@ -34,19 +36,17 @@ import Hakyll.Core.Store -- | Environment in which a compiler runs data CompilerRead = CompilerRead { -- | Target identifier - compilerIdentifier :: Identifier + compilerIdentifier :: Identifier , -- | Resource provider - compilerResourceProvider :: ResourceProvider + compilerProvider :: ResourceProvider , -- | List of all known identifiers - compilerUniverse :: [Identifier] + compilerUniverse :: [Identifier] , -- | Site routes - compilerRoutes :: Routes + compilerRoutes :: Routes , -- | Compiler store - compilerStore :: Store - , -- | Flag indicating if the underlying resource was modified - compilerResourceModified :: Bool + compilerStore :: Store , -- | Logger - compilerLogger :: Logger + compilerLogger :: Logger } @@ -111,7 +111,10 @@ instance Applicative Compiler where -------------------------------------------------------------------------------- runCompiler :: Compiler a -> CompilerRead -> IO (CompilerResult a) -runCompiler = unCompiler +runCompiler compiler read' = handle handler $ unCompiler compiler read' + where + handler :: SomeException -> IO (CompilerResult a) + handler e = return $ CompilerError $ show e -------------------------------------------------------------------------------- @@ -128,7 +131,7 @@ compilerAsk = Compiler $ \r -> return $ CompilerDone r mempty -------------------------------------------------------------------------------- -compilerTell :: [Dependency] -> Compiler () +compilerTell :: CompilerWrite -> Compiler () compilerTell deps = Compiler $ \_ -> return $ CompilerDone () deps {-# INLINE compilerTell #-} @@ -154,3 +157,11 @@ compilerCatch (Compiler x) f = Compiler $ \r -> do compilerResult :: CompilerResult a -> Compiler a compilerResult x = Compiler $ \_ -> return x {-# INLINE compilerResult #-} + + +-------------------------------------------------------------------------------- +compilerUnsafeIO :: IO a -> Compiler a +compilerUnsafeIO io = Compiler $ \_ -> do + x <- io + return $ CompilerDone x mempty +{-# INLINE compilerUnsafeIO #-} diff --git a/src/Hakyll/Core/Compiler/Require.hs b/src/Hakyll/Core/Compiler/Require.hs new file mode 100644 index 0000000..1dc96e7 --- /dev/null +++ b/src/Hakyll/Core/Compiler/Require.hs @@ -0,0 +1,63 @@ +-------------------------------------------------------------------------------- +module Hakyll.Core.Compiler.Require + ( save + , require + , requireAll + ) where + + +-------------------------------------------------------------------------------- +import Control.Applicative ((<$>)) +import Data.Binary (Binary) +import Data.Typeable + + +-------------------------------------------------------------------------------- +import Hakyll.Core.Compiler.Internal +import Hakyll.Core.Dependencies +import Hakyll.Core.Identifier +import Hakyll.Core.Identifier.Pattern +import Hakyll.Core.Store (Store) +import qualified Hakyll.Core.Store as Store + + +-------------------------------------------------------------------------------- +save :: (Binary a, Typeable a) => Store -> Identifier -> a -> IO () +save store identifier x = Store.set store (key identifier) x + + +-------------------------------------------------------------------------------- +require :: (Binary a, Typeable a) => Identifier -> Compiler a +require id' = do + store <- compilerStore <$> compilerAsk + + compilerTell [Identifier id'] + compilerResult $ CompilerRequire id' $ do + result <- compilerUnsafeIO $ Store.get store (key id') + case result of + Store.NotFound -> compilerThrow notFound + Store.WrongType e r -> compilerThrow $ wrongType e r + Store.Found x -> return x + where + notFound = + "Hakyll.Core.Compiler.Require.require: " ++ show id' ++ " was " ++ + "not found in the cache, the cache might be corrupted or " ++ + "the item you are referring to might not exist" + wrongType e r = + "Hakyll.Core.Compiler.Require.require: " ++ show id' ++ " was found " ++ + "in the cache, but does not have the right type: expected " ++ show e ++ + " but got " ++ show r + + +-------------------------------------------------------------------------------- +requireAll :: (Binary a, Typeable a) => Pattern -> Compiler [a] +requireAll pattern = do + universe <- compilerUniverse <$> compilerAsk + let matching = filterMatches pattern universe + compilerTell [Pattern pattern matching] + mapM require matching + + +-------------------------------------------------------------------------------- +key :: Identifier -> [String] +key identifier = ["Hakyll.Core.Compiler.Require", show identifier] |