{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeOperators #-}
module Polysemy.FSKVStore (
FSKVStore
, runFSKVStoreRelBS
, runFSKVStoreAbsBS
, runFSKVStoreRelUtf8
, runFSKVStoreAbsUtf8
) where
import Data.ByteString as BS
import Path
import Polysemy
import Polysemy.KVStore
import RIO (Text, readFileUtf8, writeFileUtf8)
import qualified UnliftIO.Path.Directory as U
-- | Type synonym for a KVStore indexed by files.
type FSKVStore b a = KVStore (Path b File) a
-- | Run an `FSKVStore Rel ByteString` in the supplied directory in IO.
runFSKVStoreRelBS :: Members '[Embed IO] r
=> Path b Dir
-> Sem (FSKVStore Rel ByteString ': r) a
-> Sem r a
runFSKVStoreRelBS d = interpret \case
LookupKV k -> embed $ do
z <- U.doesFileExist (d </> k)
if z
then fmap Just . BS.readFile $ toFilePath $ d </> k
else return Nothing
UpdateKV k v -> embed $ do
U.createDirectoryIfMissing True (d </> parent k)
case v of
Nothing -> pure ()
Just x -> BS.writeFile (toFilePath (d </> k)) x
-- | Run an `FSKVStore Abs ByteString` in IO.
runFSKVStoreAbsBS :: Members '[Embed IO] r
=> Sem (FSKVStore Abs ByteString ': r) a
-> Sem r a
runFSKVStoreAbsBS = interpret \case
LookupKV k -> embed $ do
z <- U.doesFileExist k
if z
then fmap Just . BS.readFile $ toFilePath k
else return Nothing
UpdateKV k v -> embed $ do
U.createDirectoryIfMissing True (parent k)
case v of
Nothing -> pure ()
Just x -> BS.writeFile (toFilePath k) x
-- | Run an `FSKVStore Rel Text` in the supplied directory in IO as UTF8.
runFSKVStoreRelUtf8 :: Members '[Embed IO] r
=> Path b Dir
-> Sem (FSKVStore Rel Text ': r) a
-> Sem r a
runFSKVStoreRelUtf8 d = interpret \case
LookupKV k -> do
z <- U.doesFileExist (d </> k)
if z
then fmap Just . readFileUtf8 $ toFilePath $ d </> k
else return Nothing
UpdateKV k v -> do
U.createDirectoryIfMissing True (d </> parent k)
case v of
Nothing -> pure ()
Just x -> writeFileUtf8 (toFilePath (d </> k)) x
-- | Run an `FSKVStore Abs Text` in IO as UTF8.
runFSKVStoreAbsUtf8 :: Members '[Embed IO] r
=> Sem (FSKVStore Abs Text ': r) a
-> Sem r a
runFSKVStoreAbsUtf8 = interpret \case
LookupKV k -> do
z <- U.doesFileExist k
if z
then fmap Just . readFileUtf8 $ toFilePath k
else return Nothing
UpdateKV k v -> do
U.createDirectoryIfMissing True (parent k)
case v of
Nothing -> pure ()
Just x -> writeFileUtf8 (toFilePath k) x