module Dingo.Internal.ResourceBundle.Internal
( ResourceBundle
, ResourceBundleSet
, ResourceDirectory
, makeResourceBundle
, elemResourceBundleSet
, embedDir
, findResourceInBundleSet
, getResourceBundleContents
, resourceBundleSetFromList
) where
import Data.ByteString (ByteString)
import qualified Data.ByteString.Lazy as BSL
import Data.Digest.Pure.SHA (sha256, showDigest)
import Data.FileEmbed
import qualified Data.Label as L
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as H
import Data.Monoid (Monoid(..))
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TLE
type ResourceDirectory = [(String, ByteString)]
data ResourceBundle =
ResourceBundle { _rbGUID :: Text
, _rbDirectory :: HashMap Text ByteString
}
$(L.mkLabels [''ResourceBundle])
newtype ResourceBundleSet = ResourceBundleSet (HashMap Text ResourceBundle)
makeResourceBundle :: ResourceDirectory -> ResourceBundle
makeResourceBundle resourceDirectory =
ResourceBundle guid resourceDirectory'
where
guid =
T.pack $ showDigest $ sha256 $ BSL.concat $
map (\(p,c) -> BSL.concat [ TLE.encodeUtf8 $ TL.pack p, BSL.fromChunks [c]]) $
resourceDirectory
resourceDirectory' =
H.fromList $ map convertFilePath resourceDirectory
convertFilePath (p,c) =
(T.pack p, c)
getResourceBundleContents :: ResourceBundle -> (Text, [(Text,ByteString)])
getResourceBundleContents (ResourceBundle guid directory) =
(guid, H.toList directory)
resourceBundleSetFromList :: [ResourceBundle] -> ResourceBundleSet
resourceBundleSetFromList =
ResourceBundleSet . H.fromList . map (\i -> (L.get rbGUID i, i))
findResource :: ResourceBundle -> Text -> Maybe ByteString
findResource bundle path =
H.lookup path $ L.get rbDirectory bundle
instance Monoid ResourceBundleSet where
mempty = ResourceBundleSet H.empty
mappend (ResourceBundleSet a) (ResourceBundleSet b) = ResourceBundleSet (a `mappend` b)
findResourceInBundleSet :: Text -> [Text] -> ResourceBundleSet -> Maybe ByteString
findResourceInBundleSet bundleId path (ResourceBundleSet resourceBundles) =
case H.lookup bundleId resourceBundles of
Nothing -> Nothing
Just resourceBundle -> findResource resourceBundle path'
where
path' :: Text
path' = T.intercalate "/" path
elemResourceBundleSet :: ResourceBundle -> ResourceBundleSet -> Bool
elemResourceBundleSet x (ResourceBundleSet xs) =
case H.lookup (L.get rbGUID x) xs of
Nothing -> False
Just _ -> True