-- | Provides a dynamic effect for "System.PosixCompat.Files".
--
-- @since 0.1
module Effectful.PosixCompat.Files.Dynamic
  ( -- * Effect
    PosixCompatFiles (..),
    setFileMode,
    setFdMode,
    setFileCreationMask,
    fileAccess,
    fileExist,
    getFileStatus,
    getFdStatus,
    getSymbolicLinkStatus,
    createNamedPipe,
    createDevice,
    createLink,
    removeLink,
    createSymbolicLink,
    readSymbolicLink,
    rename,
    setOwnerAndGroup,
    setFdOwnerAndGroup,
    setSymbolicLinkOwnerAndGroup,
    setFileTimes,
    touchFile,
    setFileSize,
    setFdSize,
    getPathVar,
    getFdPathVar,

    -- ** Handler
    runPosixFilesCompat,

    -- * PathType
    PathType (..),
    displayPathType,

    -- ** Functions
    throwIfWrongPathType,
    isPathType,
    getPathType,
  )
where

import Control.Monad (unless)
import Data.Functor ((<&>))
import Effectful
  ( Dispatch (Dynamic),
    DispatchOf,
    Eff,
    Effect,
    IOE,
    type (:>),
  )
import Effectful.Dispatch.Dynamic (HasCallStack, reinterpret_, send)
import Effectful.Dynamic.Utils (ShowEffect (showEffectCons))
import Effectful.PosixCompat.Files.Static qualified as Static
import FileSystem.IO qualified as FS.IO
import FileSystem.PathType
  ( PathType
      ( PathTypeDirectory,
        PathTypeFile,
        PathTypeOther,
        PathTypeSymbolicLink
      ),
    displayPathType,
  )
import GHC.IO.Exception (IOErrorType (InappropriateType))
import System.PosixCompat.Files (FileStatus, PathVar)
import System.PosixCompat.Files qualified as PFiles
import System.PosixCompat.Types
  ( DeviceID,
    EpochTime,
    Fd,
    FileMode,
    FileOffset,
    GroupID,
    Limit,
    UserID,
  )

-- | Dynamic effect for "System.PosixCompat.Files".
--
-- @since 0.1
data PosixCompatFiles :: Effect where
  SetFileMode :: FilePath -> FileMode -> PosixCompatFiles m ()
  SetFdMode :: Fd -> FileMode -> PosixCompatFiles m ()
  SetFileCreationMask :: FileMode -> PosixCompatFiles m FileMode
  FileAccess :: FilePath -> Bool -> Bool -> Bool -> PosixCompatFiles m Bool
  FileExist :: FilePath -> PosixCompatFiles m Bool
  GetFileStatus :: FilePath -> PosixCompatFiles m FileStatus
  GetFdStatus :: Fd -> PosixCompatFiles m FileStatus
  GetSymbolicLinkStatus :: FilePath -> PosixCompatFiles m FileStatus
  CreateNamedPipe :: FilePath -> FileMode -> PosixCompatFiles m ()
  CreateDevice :: FilePath -> FileMode -> DeviceID -> PosixCompatFiles m ()
  CreateLink :: FilePath -> FilePath -> PosixCompatFiles m ()
  RemoveLink :: FilePath -> PosixCompatFiles m ()
  CreateSymbolicLink :: FilePath -> FilePath -> PosixCompatFiles m ()
  ReadSymbolicLink :: FilePath -> PosixCompatFiles m FilePath
  Rename :: FilePath -> FilePath -> PosixCompatFiles m ()
  SetOwnerAndGroup :: FilePath -> UserID -> GroupID -> PosixCompatFiles m ()
  SetFdOwnerAndGroup :: Fd -> UserID -> GroupID -> PosixCompatFiles m ()
  SetSymbolicLinkOwnerAndGroup ::
    FilePath -> UserID -> GroupID -> PosixCompatFiles m ()
  SetFileTimes :: FilePath -> EpochTime -> EpochTime -> PosixCompatFiles m ()
  TouchFile :: FilePath -> PosixCompatFiles m ()
  SetFileSize :: FilePath -> FileOffset -> PosixCompatFiles m ()
  SetFdSize :: Fd -> FileOffset -> PosixCompatFiles m ()
  GetPathVar :: FilePath -> PathVar -> PosixCompatFiles m Limit
  GetFdPathVar :: Fd -> PathVar -> PosixCompatFiles m Limit

-- | @since 0.1
type instance DispatchOf PosixCompatFiles = Dynamic

-- | @since 0.1
instance ShowEffect PosixCompatFiles where
  showEffectCons :: forall (m :: * -> *) a. PosixCompatFiles m a -> String
showEffectCons = \case
    SetFileMode String
_ FileMode
_ -> String
"SetFileMode"
    SetFdMode Fd
_ FileMode
_ -> String
"SetFdMode"
    SetFileCreationMask FileMode
_ -> String
"SetFileCreationMask"
    FileAccess String
_ Bool
_ Bool
_ Bool
_ -> String
"FileAccess"
    FileExist String
_ -> String
"FileExist"
    GetFileStatus String
_ -> String
"GetFileStatus"
    GetFdStatus Fd
_ -> String
"GetFdStatus"
    GetSymbolicLinkStatus String
_ -> String
"GetSymbolicLinkStatus"
    CreateNamedPipe String
_ FileMode
_ -> String
"CreateNamedPipe"
    CreateDevice String
_ FileMode
_ DeviceID
_ -> String
"CreateDevice"
    CreateLink String
_ String
_ -> String
"CreateLink"
    RemoveLink String
_ -> String
"RemoveLink"
    CreateSymbolicLink String
_ String
_ -> String
"CreateSymbolicLink"
    ReadSymbolicLink String
_ -> String
"ReadSymbolicLink"
    Rename String
_ String
_ -> String
"Rename"
    SetOwnerAndGroup String
_ UserID
_ GroupID
_ -> String
"SetOwnerAndGroup"
    SetFdOwnerAndGroup Fd
_ UserID
_ GroupID
_ -> String
"SetFdOwnerAndGroup"
    SetSymbolicLinkOwnerAndGroup String
_ UserID
_ GroupID
_ -> String
"SetSymbolicLinkOwnerAndGroup"
    SetFileTimes String
_ EpochTime
_ EpochTime
_ -> String
"SetFileTimes"
    TouchFile String
_ -> String
"TouchFile"
    SetFileSize String
_ FileOffset
_ -> String
"SetFileSize"
    SetFdSize Fd
_ FileOffset
_ -> String
"SetFdSize"
    GetPathVar String
_ PathVar
_ -> String
"GetPathVar"
    GetFdPathVar Fd
_ PathVar
_ -> String
"GetFdPathVar"

-- | Runs 'PosixCompatFiles' in 'IO'.
--
-- @since 0.1
runPosixFilesCompat ::
  (HasCallStack, IOE :> es) =>
  Eff (PosixCompatFiles : es) a ->
  Eff es a
runPosixFilesCompat :: forall (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, IOE :> es) =>
Eff (PosixCompatFiles : es) a -> Eff es a
runPosixFilesCompat = (Eff (PosixCompatFiles : es) a -> Eff es a)
-> EffectHandler_ PosixCompatFiles (PosixCompatFiles : es)
-> Eff (PosixCompatFiles : es) a
-> Eff es a
forall (e :: (* -> *) -> * -> *)
       (handlerEs :: [(* -> *) -> * -> *]) a (es :: [(* -> *) -> * -> *])
       b.
(HasCallStack, DispatchOf e ~ 'Dynamic) =>
(Eff handlerEs a -> Eff es b)
-> EffectHandler_ e handlerEs -> Eff (e : es) a -> Eff es b
reinterpret_ Eff (PosixCompatFiles : es) a -> Eff es a
forall (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, IOE :> es) =>
Eff (PosixCompatFiles : es) a -> Eff es a
Static.runPosixFilesCompat (EffectHandler_ PosixCompatFiles (PosixCompatFiles : es)
 -> Eff (PosixCompatFiles : es) a -> Eff es a)
-> EffectHandler_ PosixCompatFiles (PosixCompatFiles : es)
-> Eff (PosixCompatFiles : es) a
-> Eff es a
forall a b. (a -> b) -> a -> b
$ \case
  SetFileMode String
p FileMode
m -> String -> FileMode -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> FileMode -> Eff es ()
Static.setFileMode String
p FileMode
m
  SetFdMode Fd
fd FileMode
m -> Fd -> FileMode -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
Fd -> FileMode -> Eff es ()
Static.setFdMode Fd
fd FileMode
m
  SetFileCreationMask FileMode
m -> FileMode -> Eff (PosixCompatFiles : es) FileMode
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
FileMode -> Eff es FileMode
Static.setFileCreationMask FileMode
m
  FileAccess String
p Bool
b Bool
c Bool
d -> String -> Bool -> Bool -> Bool -> Eff (PosixCompatFiles : es) Bool
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Bool -> Bool -> Bool -> Eff es Bool
Static.fileAccess String
p Bool
b Bool
c Bool
d
  FileExist String
p -> String -> Eff (PosixCompatFiles : es) Bool
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es Bool
Static.fileExist String
p
  GetFileStatus String
p -> String -> Eff (PosixCompatFiles : es) FileStatus
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es FileStatus
Static.getFileStatus String
p
  GetFdStatus Fd
fd -> Fd -> Eff (PosixCompatFiles : es) FileStatus
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
Fd -> Eff es FileStatus
Static.getFdStatus Fd
fd
  GetSymbolicLinkStatus String
p -> String -> Eff (PosixCompatFiles : es) FileStatus
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es FileStatus
Static.getSymbolicLinkStatus String
p
  CreateNamedPipe String
p FileMode
m -> String -> FileMode -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> FileMode -> Eff es ()
Static.createNamedPipe String
p FileMode
m
  CreateDevice String
p FileMode
m DeviceID
did -> String -> FileMode -> DeviceID -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> FileMode -> DeviceID -> Eff es ()
Static.createDevice String
p FileMode
m DeviceID
did
  CreateLink String
p1 String
p2 -> String -> String -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> String -> Eff es ()
Static.createLink String
p1 String
p2
  RemoveLink String
p -> String -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es ()
Static.removeLink String
p
  CreateSymbolicLink String
p1 String
p2 -> String -> String -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> String -> Eff es ()
Static.createSymbolicLink String
p1 String
p2
  ReadSymbolicLink String
p -> String -> Eff (PosixCompatFiles : es) String
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es String
Static.readSymbolicLink String
p
  Rename String
p1 String
p2 -> String -> String -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> String -> Eff es ()
Static.rename String
p1 String
p2
  SetOwnerAndGroup String
p UserID
uid GroupID
gid -> String -> UserID -> GroupID -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> UserID -> GroupID -> Eff es ()
Static.setOwnerAndGroup String
p UserID
uid GroupID
gid
  SetFdOwnerAndGroup Fd
fd UserID
uid GroupID
gid ->
    Fd -> UserID -> GroupID -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
Fd -> UserID -> GroupID -> Eff es ()
Static.setFdOwnerAndGroup Fd
fd UserID
uid GroupID
gid
  SetSymbolicLinkOwnerAndGroup String
p UserID
uid GroupID
gid ->
    String -> UserID -> GroupID -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> UserID -> GroupID -> Eff es ()
Static.setSymbolicLinkOwnerAndGroup String
p UserID
uid GroupID
gid
  SetFileTimes String
p EpochTime
t1 EpochTime
t2 -> String -> EpochTime -> EpochTime -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> EpochTime -> EpochTime -> Eff es ()
Static.setFileTimes String
p EpochTime
t1 EpochTime
t2
  TouchFile String
p -> String -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es ()
Static.touchFile String
p
  SetFileSize String
p FileOffset
oset -> String -> FileOffset -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> FileOffset -> Eff es ()
Static.setFileSize String
p FileOffset
oset
  SetFdSize Fd
fd FileOffset
oset -> Fd -> FileOffset -> Eff (PosixCompatFiles : es) ()
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
Fd -> FileOffset -> Eff es ()
Static.setFdSize Fd
fd FileOffset
oset
  GetPathVar String
p PathVar
m -> String -> PathVar -> Eff (PosixCompatFiles : es) CLong
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> PathVar -> Eff es CLong
Static.getPathVar String
p PathVar
m
  GetFdPathVar Fd
fd PathVar
m -> Fd -> PathVar -> Eff (PosixCompatFiles : es) CLong
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
Fd -> PathVar -> Eff es CLong
Static.getFdPathVar Fd
fd PathVar
m

-- | Lifted 'PFiles.setFileMode'.
--
-- @since 0.1
setFileMode ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  FileMode ->
  Eff es ()
setFileMode :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> FileMode -> Eff es ()
setFileMode String
p = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (FileMode -> PosixCompatFiles (Eff es) ())
-> FileMode
-> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FileMode -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *). String -> FileMode -> PosixCompatFiles m ()
SetFileMode String
p

-- | Lifted 'PFiles.setFdMode'.
--
-- @since 0.1
setFdMode ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  Fd ->
  FileMode ->
  Eff es ()
setFdMode :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
Fd -> FileMode -> Eff es ()
setFdMode Fd
p = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (FileMode -> PosixCompatFiles (Eff es) ())
-> FileMode
-> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fd -> FileMode -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *). Fd -> FileMode -> PosixCompatFiles m ()
SetFdMode Fd
p

-- | Lifted 'PFiles.setFileCreationMask'.
--
-- @since 0.1
setFileCreationMask ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FileMode ->
  Eff es FileMode
setFileCreationMask :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
FileMode -> Eff es FileMode
setFileCreationMask = PosixCompatFiles (Eff es) FileMode -> Eff es FileMode
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) FileMode -> Eff es FileMode)
-> (FileMode -> PosixCompatFiles (Eff es) FileMode)
-> FileMode
-> Eff es FileMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FileMode -> PosixCompatFiles (Eff es) FileMode
forall (m :: * -> *). FileMode -> PosixCompatFiles m FileMode
SetFileCreationMask

-- | Lifted 'PFiles.fileAccess'.
--
-- @since 0.1
fileAccess ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  Bool ->
  Bool ->
  Bool ->
  Eff es Bool
fileAccess :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Bool -> Bool -> Bool -> Eff es Bool
fileAccess String
p Bool
b Bool
c = PosixCompatFiles (Eff es) Bool -> Eff es Bool
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) Bool -> Eff es Bool)
-> (Bool -> PosixCompatFiles (Eff es) Bool) -> Bool -> Eff es Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Bool -> Bool -> Bool -> PosixCompatFiles (Eff es) Bool
forall (m :: * -> *).
String -> Bool -> Bool -> Bool -> PosixCompatFiles m Bool
FileAccess String
p Bool
b Bool
c

-- | Lifted 'PFiles.fileExist'.
--
-- @since 0.1
fileExist ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  Eff es Bool
fileExist :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es Bool
fileExist = PosixCompatFiles (Eff es) Bool -> Eff es Bool
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) Bool -> Eff es Bool)
-> (String -> PosixCompatFiles (Eff es) Bool)
-> String
-> Eff es Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> PosixCompatFiles (Eff es) Bool
forall (m :: * -> *). String -> PosixCompatFiles m Bool
FileExist

-- | Lifted 'PFiles.getFileStatus'.
--
-- @since 0.1
getFileStatus ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  Eff es FileStatus
getFileStatus :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es FileStatus
getFileStatus = PosixCompatFiles (Eff es) FileStatus -> Eff es FileStatus
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) FileStatus -> Eff es FileStatus)
-> (String -> PosixCompatFiles (Eff es) FileStatus)
-> String
-> Eff es FileStatus
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> PosixCompatFiles (Eff es) FileStatus
forall (m :: * -> *). String -> PosixCompatFiles m FileStatus
GetFileStatus

-- | Lifted 'PFiles.getFdStatus'.
--
-- @since 0.1
getFdStatus ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  Fd ->
  Eff es FileStatus
getFdStatus :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
Fd -> Eff es FileStatus
getFdStatus = PosixCompatFiles (Eff es) FileStatus -> Eff es FileStatus
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) FileStatus -> Eff es FileStatus)
-> (Fd -> PosixCompatFiles (Eff es) FileStatus)
-> Fd
-> Eff es FileStatus
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fd -> PosixCompatFiles (Eff es) FileStatus
forall (m :: * -> *). Fd -> PosixCompatFiles m FileStatus
GetFdStatus

-- | Lifted 'PFiles.getSymbolicLinkStatus'.
--
-- @since 0.1
getSymbolicLinkStatus ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  Eff es FileStatus
getSymbolicLinkStatus :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es FileStatus
getSymbolicLinkStatus = PosixCompatFiles (Eff es) FileStatus -> Eff es FileStatus
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) FileStatus -> Eff es FileStatus)
-> (String -> PosixCompatFiles (Eff es) FileStatus)
-> String
-> Eff es FileStatus
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> PosixCompatFiles (Eff es) FileStatus
forall (m :: * -> *). String -> PosixCompatFiles m FileStatus
GetSymbolicLinkStatus

-- | Lifted 'PFiles.createNamedPipe'.
--
-- @since 0.1
createNamedPipe ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  FileMode ->
  Eff es ()
createNamedPipe :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> FileMode -> Eff es ()
createNamedPipe String
p = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (FileMode -> PosixCompatFiles (Eff es) ())
-> FileMode
-> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FileMode -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *). String -> FileMode -> PosixCompatFiles m ()
CreateNamedPipe String
p

-- | Lifted 'PFiles.createDevice'.
--
-- @since 0.1
createDevice ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  FileMode ->
  DeviceID ->
  Eff es ()
createDevice :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> FileMode -> DeviceID -> Eff es ()
createDevice String
p FileMode
m = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (DeviceID -> PosixCompatFiles (Eff es) ())
-> DeviceID
-> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FileMode -> DeviceID -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *).
String -> FileMode -> DeviceID -> PosixCompatFiles m ()
CreateDevice String
p FileMode
m

-- | Lifted 'PFiles.createLink'.
--
-- @since 0.1
createLink ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  FilePath ->
  Eff es ()
createLink :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> String -> Eff es ()
createLink String
p = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (String -> PosixCompatFiles (Eff es) ()) -> String -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *). String -> String -> PosixCompatFiles m ()
CreateLink String
p

-- | Lifted 'PFiles.removeLink'.
--
-- @since 0.1
removeLink ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  Eff es ()
removeLink :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es ()
removeLink = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (String -> PosixCompatFiles (Eff es) ()) -> String -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *). String -> PosixCompatFiles m ()
RemoveLink

-- | Lifted 'PFiles.createSymbolicLink'.
--
-- @since 0.1
createSymbolicLink ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  FilePath ->
  Eff es ()
createSymbolicLink :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> String -> Eff es ()
createSymbolicLink String
p = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (String -> PosixCompatFiles (Eff es) ()) -> String -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *). String -> String -> PosixCompatFiles m ()
CreateSymbolicLink String
p

-- | Lifted 'PFiles.readSymbolicLink'.
--
-- @since 0.1
readSymbolicLink ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  Eff es FilePath
readSymbolicLink :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es String
readSymbolicLink = PosixCompatFiles (Eff es) String -> Eff es String
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) String -> Eff es String)
-> (String -> PosixCompatFiles (Eff es) String)
-> String
-> Eff es String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> PosixCompatFiles (Eff es) String
forall (m :: * -> *). String -> PosixCompatFiles m String
ReadSymbolicLink

-- | Lifted 'PFiles.rename'.
--
-- @since 0.1
rename ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  FilePath ->
  Eff es ()
rename :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> String -> Eff es ()
rename String
p = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (String -> PosixCompatFiles (Eff es) ()) -> String -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *). String -> String -> PosixCompatFiles m ()
Rename String
p

-- | Lifted 'PFiles.setOwnerAndGroup'.
--
-- @since 0.1
setOwnerAndGroup ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  UserID ->
  GroupID ->
  Eff es ()
setOwnerAndGroup :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> UserID -> GroupID -> Eff es ()
setOwnerAndGroup String
p UserID
uid = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (GroupID -> PosixCompatFiles (Eff es) ())
-> GroupID
-> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> UserID -> GroupID -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *).
String -> UserID -> GroupID -> PosixCompatFiles m ()
SetOwnerAndGroup String
p UserID
uid

-- | Lifted 'PFiles.setFdOwnerAndGroup'.
--
-- @since 0.1
setFdOwnerAndGroup ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  Fd ->
  UserID ->
  GroupID ->
  Eff es ()
setFdOwnerAndGroup :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
Fd -> UserID -> GroupID -> Eff es ()
setFdOwnerAndGroup Fd
fd UserID
uid = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (GroupID -> PosixCompatFiles (Eff es) ())
-> GroupID
-> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fd -> UserID -> GroupID -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *).
Fd -> UserID -> GroupID -> PosixCompatFiles m ()
SetFdOwnerAndGroup Fd
fd UserID
uid

-- | Lifted 'PFiles.setSymbolicLinkOwnerAndGroup'.
--
-- @since 0.1
setSymbolicLinkOwnerAndGroup ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  UserID ->
  GroupID ->
  Eff es ()
setSymbolicLinkOwnerAndGroup :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> UserID -> GroupID -> Eff es ()
setSymbolicLinkOwnerAndGroup String
p UserID
uid = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (GroupID -> PosixCompatFiles (Eff es) ())
-> GroupID
-> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> UserID -> GroupID -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *).
String -> UserID -> GroupID -> PosixCompatFiles m ()
SetSymbolicLinkOwnerAndGroup String
p UserID
uid

-- | Lifted 'PFiles.setFileTimes'.
--
-- @since 0.1
setFileTimes ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  EpochTime ->
  EpochTime ->
  Eff es ()
setFileTimes :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> EpochTime -> EpochTime -> Eff es ()
setFileTimes String
p EpochTime
t = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (EpochTime -> PosixCompatFiles (Eff es) ())
-> EpochTime
-> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> EpochTime -> EpochTime -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *).
String -> EpochTime -> EpochTime -> PosixCompatFiles m ()
SetFileTimes String
p EpochTime
t

-- | Lifted 'PFiles.touchFile'.
--
-- @since 0.1
touchFile ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  Eff es ()
touchFile :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es ()
touchFile = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (String -> PosixCompatFiles (Eff es) ()) -> String -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *). String -> PosixCompatFiles m ()
TouchFile

-- | Lifted 'PFiles.setFileSize'.
--
-- @since 0.1
setFileSize ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  FileOffset ->
  Eff es ()
setFileSize :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> FileOffset -> Eff es ()
setFileSize String
p = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (FileOffset -> PosixCompatFiles (Eff es) ())
-> FileOffset
-> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FileOffset -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *). String -> FileOffset -> PosixCompatFiles m ()
SetFileSize String
p

-- | Lifted 'PFiles.setFdSize'.
--
-- @since 0.1
setFdSize ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  Fd ->
  FileOffset ->
  Eff es ()
setFdSize :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
Fd -> FileOffset -> Eff es ()
setFdSize Fd
fd = PosixCompatFiles (Eff es) () -> Eff es ()
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) () -> Eff es ())
-> (FileOffset -> PosixCompatFiles (Eff es) ())
-> FileOffset
-> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fd -> FileOffset -> PosixCompatFiles (Eff es) ()
forall (m :: * -> *). Fd -> FileOffset -> PosixCompatFiles m ()
SetFdSize Fd
fd

-- | Lifted 'PFiles.getPathVar'.
--
-- @since 0.1
getPathVar ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  PathVar ->
  Eff es Limit
getPathVar :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> PathVar -> Eff es CLong
getPathVar String
p = PosixCompatFiles (Eff es) CLong -> Eff es CLong
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) CLong -> Eff es CLong)
-> (PathVar -> PosixCompatFiles (Eff es) CLong)
-> PathVar
-> Eff es CLong
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> PathVar -> PosixCompatFiles (Eff es) CLong
forall (m :: * -> *). String -> PathVar -> PosixCompatFiles m CLong
GetPathVar String
p

-- | Lifted 'PFiles.getFdPathVar'.
--
-- @since 0.1
getFdPathVar ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  Fd ->
  PathVar ->
  Eff es Limit
getFdPathVar :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
Fd -> PathVar -> Eff es CLong
getFdPathVar Fd
fd = PosixCompatFiles (Eff es) CLong -> Eff es CLong
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (PosixCompatFiles (Eff es) CLong -> Eff es CLong)
-> (PathVar -> PosixCompatFiles (Eff es) CLong)
-> PathVar
-> Eff es CLong
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fd -> PathVar -> PosixCompatFiles (Eff es) CLong
forall (m :: * -> *). Fd -> PathVar -> PosixCompatFiles m CLong
GetFdPathVar Fd
fd

-- | Throws 'IOException' if the path does not exist or the expected path type
-- does not match actual.
--
-- @since 0.1
throwIfWrongPathType ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  String ->
  PathType ->
  FilePath ->
  Eff es ()
throwIfWrongPathType :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> PathType -> String -> Eff es ()
throwIfWrongPathType String
location PathType
expected String
path = do
  actual <- String -> Eff es PathType
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es PathType
getPathType String
path

  let err =
        [String] -> String
forall a. Monoid a => [a] -> a
mconcat
          [ String
"Expected path to have type ",
            PathType -> String
forall a. IsString a => PathType -> a
displayPathType PathType
expected,
            String
", but detected ",
            PathType -> String
forall a. IsString a => PathType -> a
displayPathType PathType
actual
          ]

  unless (expected == actual) $
    FS.IO.throwFilePathIOError
      path
      location
      InappropriateType
      err

-- | Checks that the path type matches the expectation. Throws
-- 'IOException' if the path does not exist or the type cannot be detected.
--
-- @since 0.1
isPathType ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  PathType ->
  FilePath ->
  Eff es Bool
isPathType :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
PathType -> String -> Eff es Bool
isPathType PathType
expected = (PathType -> Bool) -> Eff es PathType -> Eff es Bool
forall a b. (a -> b) -> Eff es a -> Eff es b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PathType -> PathType -> Bool
forall a. Eq a => a -> a -> Bool
== PathType
expected) (Eff es PathType -> Eff es Bool)
-> (String -> Eff es PathType) -> String -> Eff es Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Eff es PathType
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es PathType
getPathType

-- | Returns the type for a given path without following symlinks.
-- Throws 'IOException' if the path does not exist or the type cannot be
-- detected.
--
-- @since 0.1
getPathType ::
  ( HasCallStack,
    PosixCompatFiles :> es
  ) =>
  FilePath ->
  Eff es PathType
getPathType :: forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es PathType
getPathType String
path =
  String -> Eff es FileStatus
forall (es :: [(* -> *) -> * -> *]).
(HasCallStack, PosixCompatFiles :> es) =>
String -> Eff es FileStatus
getSymbolicLinkStatus String
path Eff es FileStatus -> (FileStatus -> PathType) -> Eff es PathType
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \FileStatus
status ->
    if
      | FileStatus -> Bool
PFiles.isSymbolicLink FileStatus
status -> PathType
PathTypeSymbolicLink
      | FileStatus -> Bool
PFiles.isDirectory FileStatus
status -> PathType
PathTypeDirectory
      | FileStatus -> Bool
PFiles.isRegularFile FileStatus
status -> PathType
PathTypeFile
      | Bool
otherwise -> PathType
PathTypeOther