-- | Provides the MonadFileWriter effect.
--
-- @since 0.1
module Effects.FileSystem.FileWriter
  ( -- * Effect
    MonadFileWriter (..),
    OsPath,

    -- * UTF-8 Utils
    writeFileUtf8,
    appendFileUtf8,
    FS.UTF8.encodeUtf8,

    -- * Reexports
    ByteString,
    Text,
  )
where

import Control.Monad.Trans.Class (MonadTrans (lift))
import Control.Monad.Trans.Reader (ReaderT)
import Data.ByteString (ByteString)
import Data.Text (Text)
import FileSystem.IO qualified as FS.IO
import FileSystem.OsPath (OsPath)
import FileSystem.UTF8 qualified as FS.UTF8
import GHC.Stack (HasCallStack)

-- | Represents file-system writer effects.
--
-- @since 0.1
class (Monad m) => MonadFileWriter m where
  -- | Writes to a file.
  --
  -- @since 0.1
  writeBinaryFile :: (HasCallStack) => OsPath -> ByteString -> m ()

  -- | Appends to a file.
  --
  -- @since 0.1
  appendBinaryFile :: (HasCallStack) => OsPath -> ByteString -> m ()

-- | @since 0.1
instance MonadFileWriter IO where
  writeBinaryFile :: HasCallStack => OsPath -> ByteString -> IO ()
writeBinaryFile = OsPath -> ByteString -> IO ()
FS.IO.writeBinaryFileIO
  {-# INLINEABLE writeBinaryFile #-}
  appendBinaryFile :: HasCallStack => OsPath -> ByteString -> IO ()
appendBinaryFile = OsPath -> ByteString -> IO ()
FS.IO.appendBinaryFileIO
  {-# INLINEABLE appendBinaryFile #-}

-- | @since 0.1
instance (MonadFileWriter m) => MonadFileWriter (ReaderT env m) where
  writeBinaryFile :: HasCallStack => OsPath -> ByteString -> ReaderT env m ()
writeBinaryFile OsPath
p = m () -> ReaderT env m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT env m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT env m ())
-> (ByteString -> m ()) -> ByteString -> ReaderT env m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OsPath -> ByteString -> m ()
forall (m :: * -> *).
(MonadFileWriter m, HasCallStack) =>
OsPath -> ByteString -> m ()
writeBinaryFile OsPath
p
  {-# INLINEABLE writeBinaryFile #-}
  appendBinaryFile :: HasCallStack => OsPath -> ByteString -> ReaderT env m ()
appendBinaryFile OsPath
p = m () -> ReaderT env m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT env m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT env m ())
-> (ByteString -> m ()) -> ByteString -> ReaderT env m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OsPath -> ByteString -> m ()
forall (m :: * -> *).
(MonadFileWriter m, HasCallStack) =>
OsPath -> ByteString -> m ()
appendBinaryFile OsPath
p
  {-# INLINEABLE appendBinaryFile #-}

-- | Writes to a file as UTF-8.
--
-- @since 0.1
writeFileUtf8 :: (HasCallStack, MonadFileWriter m) => OsPath -> Text -> m ()
writeFileUtf8 :: forall (m :: * -> *).
(HasCallStack, MonadFileWriter m) =>
OsPath -> Text -> m ()
writeFileUtf8 OsPath
p = OsPath -> ByteString -> m ()
forall (m :: * -> *).
(MonadFileWriter m, HasCallStack) =>
OsPath -> ByteString -> m ()
writeBinaryFile OsPath
p (ByteString -> m ()) -> (Text -> ByteString) -> Text -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
FS.UTF8.encodeUtf8
{-# INLINEABLE writeFileUtf8 #-}

-- | Appends to a file as UTF-8.
--
-- @since 0.1
appendFileUtf8 :: (HasCallStack, MonadFileWriter m) => OsPath -> Text -> m ()
appendFileUtf8 :: forall (m :: * -> *).
(HasCallStack, MonadFileWriter m) =>
OsPath -> Text -> m ()
appendFileUtf8 OsPath
p = OsPath -> ByteString -> m ()
forall (m :: * -> *).
(MonadFileWriter m, HasCallStack) =>
OsPath -> ByteString -> m ()
appendBinaryFile OsPath
p (ByteString -> m ()) -> (Text -> ByteString) -> Text -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
FS.UTF8.encodeUtf8
{-# INLINEABLE appendFileUtf8 #-}