module Text.Mustache.Compile
( compileMustacheDir
, compileMustacheFile
, compileMustacheText )
where
import Control.Monad.Catch (MonadThrow (..))
import Control.Monad.Except
import Data.Text.Lazy (Text)
import System.Directory
import Text.Megaparsec
import Text.Mustache.Parser
import Text.Mustache.Type
import qualified Data.Map as M
import qualified Data.Text as T
import qualified Data.Text.Lazy.IO as TL
import qualified System.FilePath as F
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative ((<$>))
#endif
compileMustacheDir :: (MonadIO m, MonadThrow m)
=> PName
-> FilePath
-> m Template
compileMustacheDir pname path =
liftIO (getDirectoryContents path) >>=
filterM isMustacheFile . liftM (F.combine (F.takeDirectory path)) >>=
liftM selectKey . foldM f (Template undefined M.empty)
where
selectKey t = t { templateActual = pname }
f (Template _ old) fp = do
Template _ new <- compileMustacheFile fp
return (Template undefined (M.union new old))
compileMustacheFile :: (MonadIO m, MonadThrow m)
=> FilePath
-> m Template
compileMustacheFile path = liftIO (TL.readFile path) >>=
withException . compileMustacheText (pathToPName path)
compileMustacheText
:: PName
-> Text
-> Either (ParseError Char Dec) Template
compileMustacheText pname txt =
Template pname . M.singleton pname <$> parseMustache "" txt
isMustacheFile :: MonadIO m => FilePath -> m Bool
isMustacheFile path = do
exists <- liftIO (doesFileExist path)
let rightExtension = F.takeExtension path == ".mustache"
return (exists && rightExtension)
pathToPName :: FilePath -> PName
pathToPName = PName . T.pack . F.takeBaseName
withException :: MonadThrow m
=> Either (ParseError Char Dec) Template
-> m Template
withException = either (throwM . MustacheException) return