Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions effectful/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# effectful-2.7.0.0 (2026-??-??)
* Add `OsPath` variants of the `FilePath` based APIs
(`Effectful.FileSystem.OsPath` for `System.Directory.OsPath` and
`Effectful.FileSystem.File.OsPath` for `System.File.OsPath` from the
`file-io` package).
* `runInBoundThread` and `runInUnboundThread` from `Effectful.Concurrent` no
longer run the computation in a cloned environment, so changes to thread-local
effects made within are no longer discarded.
Expand Down
9 changes: 8 additions & 1 deletion effectful/effectful.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ library
build-depends: base >= 4.18 && < 5
, async >= 2.2.5
, bytestring >= 0.10
, directory >= 1.3.2
, directory >= 1.3.8
, effectful-core >= 2.7.0.0 && < 2.7.1.0
, file-io >= 0.1.4
, filepath >= 1.4.100
, process >= 1.6.9
, strict-mutable-base >= 1.1.0.0
, time >= 1.9.2
Expand All @@ -83,11 +85,13 @@ library
Effectful.Console.ByteString.Lazy
Effectful.Environment
Effectful.FileSystem
Effectful.FileSystem.File.OsPath
Effectful.FileSystem.IO
Effectful.FileSystem.IO.ByteString
Effectful.FileSystem.IO.ByteString.Builder
Effectful.FileSystem.IO.ByteString.Lazy
Effectful.FileSystem.IO.File
Effectful.FileSystem.OsPath
Effectful.Prim.IORef
Effectful.Prim.IORef.Strict
Effectful.Process
Expand Down Expand Up @@ -143,10 +147,12 @@ test-suite test
ghc-options: -threaded -rtsopts -with-rtsopts=-N4

build-depends: base
, bytestring
, containers
, effectful
, effectful-core
, exceptions
, filepath
, lifted-base
, primitive
, random
Expand All @@ -166,6 +172,7 @@ test-suite test
EnvTests
EnvironmentTests
ErrorTests
FileSystemTests
InputTests
LabeledTests
NonDetTests
Expand Down
150 changes: 150 additions & 0 deletions effectful/src/Effectful/FileSystem/File/OsPath.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
-- | Lifted "System.File.OsPath".
module Effectful.FileSystem.File.OsPath
( -- * Effect
FileSystem

-- ** Handlers
, runFileSystem

-- * Files
, IOMode (..)
, Handle
, openBinaryFile
, withFile
, withBinaryFile
, withFile'
, withBinaryFile'
, readFile
, readFile'
, writeFile
, writeFile'
, appendFile
, appendFile'
, openFile
, openExistingFile
, openTempFile
, openBinaryTempFile
, openTempFileWithDefaultPermissions
, openBinaryTempFileWithDefaultPermissions
) where

import Data.ByteString (ByteString)
import Data.ByteString.Lazy qualified as BSL
import Prelude hiding (appendFile, readFile, writeFile)
import System.File.OsPath qualified as F
import System.IO (Handle, IOMode (..))
import System.OsPath (OsPath, OsString)

import Effectful
import Effectful.Dispatch.Static
import Effectful.FileSystem.Effect

-- | Lifted 'F.openBinaryFile'.
openBinaryFile :: FileSystem :> es => OsPath -> IOMode -> Eff es Handle
openBinaryFile path = unsafeEff_ . F.openBinaryFile path

-- | Lifted 'F.withFile'.
withFile
:: FileSystem :> es
=> OsPath
-> IOMode
-> (Handle -> Eff es a)
-> Eff es a
withFile path mode inner = unsafeSeqUnliftIO $ \unlift -> do
F.withFile path mode $ unlift . inner

-- | Lifted 'F.withBinaryFile'.
withBinaryFile
:: FileSystem :> es
=> OsPath
-> IOMode
-> (Handle -> Eff es a)
-> Eff es a
withBinaryFile path mode inner = unsafeSeqUnliftIO $ \unlift -> do
F.withBinaryFile path mode $ unlift . inner

-- | Lifted 'F.withFile''.
withFile'
:: FileSystem :> es
=> OsPath
-> IOMode
-> (Handle -> Eff es a)
-> Eff es a
withFile' path mode inner = unsafeSeqUnliftIO $ \unlift -> do
F.withFile' path mode $ unlift . inner

-- | Lifted 'F.withBinaryFile''.
withBinaryFile'
:: FileSystem :> es
=> OsPath
-> IOMode
-> (Handle -> Eff es a)
-> Eff es a
withBinaryFile' path mode inner = unsafeSeqUnliftIO $ \unlift -> do
F.withBinaryFile' path mode $ unlift . inner

-- | Lifted 'F.readFile'.
readFile :: FileSystem :> es => OsPath -> Eff es BSL.ByteString
readFile = unsafeEff_ . F.readFile

-- | Lifted 'F.readFile''.
readFile' :: FileSystem :> es => OsPath -> Eff es ByteString
readFile' = unsafeEff_ . F.readFile'

-- | Lifted 'F.writeFile'.
writeFile :: FileSystem :> es => OsPath -> BSL.ByteString -> Eff es ()
writeFile path = unsafeEff_ . F.writeFile path

-- | Lifted 'F.writeFile''.
writeFile' :: FileSystem :> es => OsPath -> ByteString -> Eff es ()
writeFile' path = unsafeEff_ . F.writeFile' path

-- | Lifted 'F.appendFile'.
appendFile :: FileSystem :> es => OsPath -> BSL.ByteString -> Eff es ()
appendFile path = unsafeEff_ . F.appendFile path

-- | Lifted 'F.appendFile''.
appendFile' :: FileSystem :> es => OsPath -> ByteString -> Eff es ()
appendFile' path = unsafeEff_ . F.appendFile' path

-- | Lifted 'F.openFile'.
openFile :: FileSystem :> es => OsPath -> IOMode -> Eff es Handle
openFile path = unsafeEff_ . F.openFile path

-- | Lifted 'F.openExistingFile'.
openExistingFile :: FileSystem :> es => OsPath -> IOMode -> Eff es Handle
openExistingFile path = unsafeEff_ . F.openExistingFile path

-- | Lifted 'F.openTempFile'.
openTempFile
:: FileSystem :> es
=> OsPath
-> OsString
-> Eff es (OsPath, Handle)
openTempFile dir = unsafeEff_ . F.openTempFile dir

-- | Lifted 'F.openBinaryTempFile'.
openBinaryTempFile
:: FileSystem :> es
=> OsPath
-> OsString
-> Eff es (OsPath, Handle)
openBinaryTempFile dir = unsafeEff_ . F.openBinaryTempFile dir

-- | Lifted 'F.openTempFileWithDefaultPermissions'.
openTempFileWithDefaultPermissions
:: FileSystem :> es
=> OsPath
-> OsString
-> Eff es (OsPath, Handle)
openTempFileWithDefaultPermissions dir =
unsafeEff_ . F.openTempFileWithDefaultPermissions dir

-- | Lifted 'F.openBinaryTempFileWithDefaultPermissions'.
openBinaryTempFileWithDefaultPermissions
:: FileSystem :> es
=> OsPath
-> OsString
-> Eff es (OsPath, Handle)
openBinaryTempFileWithDefaultPermissions dir =
unsafeEff_ . F.openBinaryTempFileWithDefaultPermissions dir
Loading