summaryrefslogtreecommitdiff
path: root/lib/Hakyll/Core/Compiler/Require.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Hakyll/Core/Compiler/Require.hs')
-rw-r--r--lib/Hakyll/Core/Compiler/Require.hs121
1 files changed, 121 insertions, 0 deletions
diff --git a/lib/Hakyll/Core/Compiler/Require.hs b/lib/Hakyll/Core/Compiler/Require.hs
new file mode 100644
index 0000000..c9373bf
--- /dev/null
+++ b/lib/Hakyll/Core/Compiler/Require.hs
@@ -0,0 +1,121 @@
+--------------------------------------------------------------------------------
+module Hakyll.Core.Compiler.Require
+ ( Snapshot
+ , save
+ , saveSnapshot
+ , load
+ , loadSnapshot
+ , loadBody
+ , loadSnapshotBody
+ , loadAll
+ , loadAllSnapshots
+ ) where
+
+
+--------------------------------------------------------------------------------
+import Control.Monad (when)
+import Data.Binary (Binary)
+import qualified Data.Set as S
+import Data.Typeable
+
+
+--------------------------------------------------------------------------------
+import Hakyll.Core.Compiler.Internal
+import Hakyll.Core.Dependencies
+import Hakyll.Core.Identifier
+import Hakyll.Core.Identifier.Pattern
+import Hakyll.Core.Item
+import Hakyll.Core.Metadata
+import Hakyll.Core.Store (Store)
+import qualified Hakyll.Core.Store as Store
+
+
+--------------------------------------------------------------------------------
+save :: (Binary a, Typeable a) => Store -> Item a -> IO ()
+save store item = saveSnapshot store final item
+
+
+--------------------------------------------------------------------------------
+-- | Save a specific snapshot of an item, so you can load it later using
+-- 'loadSnapshot'.
+saveSnapshot :: (Binary a, Typeable a)
+ => Store -> Snapshot -> Item a -> IO ()
+saveSnapshot store snapshot item =
+ Store.set store (key (itemIdentifier item) snapshot) (itemBody item)
+
+
+--------------------------------------------------------------------------------
+-- | Load an item compiled elsewhere. If the required item is not yet compiled,
+-- the build system will take care of that automatically.
+load :: (Binary a, Typeable a) => Identifier -> Compiler (Item a)
+load id' = loadSnapshot id' final
+
+
+--------------------------------------------------------------------------------
+-- | Require a specific snapshot of an item.
+loadSnapshot :: (Binary a, Typeable a)
+ => Identifier -> Snapshot -> Compiler (Item a)
+loadSnapshot id' snapshot = do
+ store <- compilerStore <$> compilerAsk
+ universe <- compilerUniverse <$> compilerAsk
+
+ -- Quick check for better error messages
+ when (id' `S.notMember` universe) $ fail notFound
+
+ compilerTellDependencies [IdentifierDependency id']
+ compilerResult $ CompilerRequire (id', snapshot) $ do
+ result <- compilerUnsafeIO $ Store.get store (key id' snapshot)
+ case result of
+ Store.NotFound -> fail notFound
+ Store.WrongType e r -> fail $ wrongType e r
+ Store.Found x -> return $ Item id' x
+ where
+ notFound =
+ "Hakyll.Core.Compiler.Require.load: " ++ show id' ++
+ " (snapshot " ++ snapshot ++ ") 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.load: " ++ show id' ++
+ " (snapshot " ++ snapshot ++ ") was found in the cache, " ++
+ "but does not have the right type: expected " ++ show e ++
+ " but got " ++ show r
+
+
+--------------------------------------------------------------------------------
+-- | A shortcut for only requiring the body of an item.
+--
+-- > loadBody = fmap itemBody . load
+loadBody :: (Binary a, Typeable a) => Identifier -> Compiler a
+loadBody id' = loadSnapshotBody id' final
+
+
+--------------------------------------------------------------------------------
+loadSnapshotBody :: (Binary a, Typeable a)
+ => Identifier -> Snapshot -> Compiler a
+loadSnapshotBody id' snapshot = fmap itemBody $ loadSnapshot id' snapshot
+
+
+--------------------------------------------------------------------------------
+-- | This function allows you to 'load' a dynamic list of items
+loadAll :: (Binary a, Typeable a) => Pattern -> Compiler [Item a]
+loadAll pattern = loadAllSnapshots pattern final
+
+
+--------------------------------------------------------------------------------
+loadAllSnapshots :: (Binary a, Typeable a)
+ => Pattern -> Snapshot -> Compiler [Item a]
+loadAllSnapshots pattern snapshot = do
+ matching <- getMatches pattern
+ mapM (\i -> loadSnapshot i snapshot) matching
+
+
+--------------------------------------------------------------------------------
+key :: Identifier -> String -> [String]
+key identifier snapshot =
+ ["Hakyll.Core.Compiler.Require", show identifier, snapshot]
+
+
+--------------------------------------------------------------------------------
+final :: Snapshot
+final = "_final"