{-# OPTIONS_GHC -Wno-redundant-constraints #-}

-- | Provides a static effect for writing files.
--
-- @since 0.1
module Effectful.FileSystem.FileWriter.Static
  ( -- * Effect
    FileWriter,
    writeBinaryFile,
    appendBinaryFile,

    -- ** Handlers
    runFileWriter,

    -- * UTF-8 Utils
    writeFileUtf8,
    appendFileUtf8,

    -- * Re-exports
    ByteString,
    OsPath,
    Text,
  )
where

import Data.ByteString (ByteString)
import Data.Text (Text)
import Effectful
  ( Dispatch (Static),
    DispatchOf,
    Eff,
    Effect,
    IOE,
    type (:>),
  )
import Effectful.Dispatch.Static
  ( HasCallStack,
    SideEffects (WithSideEffects),
    StaticRep,
    evalStaticRep,
    unsafeEff_,
  )
import FileSystem.IO (appendBinaryFileIO, writeBinaryFileIO)
import FileSystem.OsPath (OsPath)
import FileSystem.UTF8 qualified as FS.UTF8

-- | Static effect for reading files.
--
-- @since 0.1
data FileWriter :: Effect

type instance DispatchOf FileWriter = Static WithSideEffects

data instance StaticRep FileWriter = MkFileWriter

-- | Runs 'FileWriter' in 'IO'.
--
-- @since 0.1
runFileWriter ::
  (HasCallStack, IOE :> es) =>
  Eff (FileWriter : es) a ->
  Eff es a
runFileWriter :: forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
Eff (FileWriter : es) a -> Eff es a
runFileWriter = StaticRep FileWriter -> Eff (FileWriter : es) a -> Eff es a
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
       a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects,
 MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep StaticRep FileWriter
MkFileWriter

-- | Writes a 'ByteString' to a file.
--
-- @since 0.1
writeBinaryFile ::
  ( FileWriter :> es,
    HasCallStack
  ) =>
  OsPath ->
  ByteString ->
  Eff es ()
writeBinaryFile :: forall (es :: [Effect]).
(FileWriter :> es, HasCallStack) =>
OsPath -> ByteString -> Eff es ()
writeBinaryFile OsPath
p = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> (ByteString -> IO ()) -> ByteString -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OsPath -> ByteString -> IO ()
writeBinaryFileIO OsPath
p

-- | Appends a 'ByteString' to a file.
--
-- @since 0.1
appendBinaryFile ::
  ( FileWriter :> es,
    HasCallStack
  ) =>
  OsPath ->
  ByteString ->
  Eff es ()
appendBinaryFile :: forall (es :: [Effect]).
(FileWriter :> es, HasCallStack) =>
OsPath -> ByteString -> Eff es ()
appendBinaryFile OsPath
p = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> (ByteString -> IO ()) -> ByteString -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OsPath -> ByteString -> IO ()
appendBinaryFileIO OsPath
p

-- | Writes the 'Text' to the file, encoding as UTF-8.
--
-- @since 0.1
writeFileUtf8 ::
  ( FileWriter :> es,
    HasCallStack
  ) =>
  OsPath ->
  Text ->
  Eff es ()
writeFileUtf8 :: forall (es :: [Effect]).
(FileWriter :> es, HasCallStack) =>
OsPath -> Text -> Eff es ()
writeFileUtf8 OsPath
f = OsPath -> ByteString -> Eff es ()
forall (es :: [Effect]).
(FileWriter :> es, HasCallStack) =>
OsPath -> ByteString -> Eff es ()
writeBinaryFile OsPath
f (ByteString -> Eff es ())
-> (Text -> ByteString) -> Text -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
FS.UTF8.encodeUtf8

-- | Appends the 'Text' to the file, encoding as UTF-8.
--
-- @since 0.1
appendFileUtf8 ::
  ( FileWriter :> es,
    HasCallStack
  ) =>
  OsPath ->
  Text ->
  Eff es ()
appendFileUtf8 :: forall (es :: [Effect]).
(FileWriter :> es, HasCallStack) =>
OsPath -> Text -> Eff es ()
appendFileUtf8 OsPath
f = OsPath -> ByteString -> Eff es ()
forall (es :: [Effect]).
(FileWriter :> es, HasCallStack) =>
OsPath -> ByteString -> Eff es ()
appendBinaryFile OsPath
f (ByteString -> Eff es ())
-> (Text -> ByteString) -> Text -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
FS.UTF8.encodeUtf8