summaryrefslogtreecommitdiff
path: root/src/Hakyll/Core/Compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/Hakyll/Core/Compiler')
-rw-r--r--src/Hakyll/Core/Compiler/Internal.hs33
-rw-r--r--src/Hakyll/Core/Compiler/Require.hs63
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]