@@ -0,0 +1,347 @@
1+module Effectful.FileSystem
5+ -- * Actions on directories
7+ , createDirectoryIfMissing
9+ , removeDirectoryRecursive
13+ , getDirectoryContents
15+ -- ** Current working directory
16+ , getCurrentDirectory
17+ , setCurrentDirectory
18+ , withCurrentDirectory
20+ -- * Pre-defined directories
23+ , getXdgDirectoryList
24+ , getAppUserDataDirectory
25+ , getUserDocumentsDirectory
26+ , getTemporaryDirectory
28+ -- * Actions on files
33+ , copyFileWithMetadata
37+ , makeRelativeToCurrentDirectory
45+ , findExecutablesInDirectories
53+ , createDirectoryLink
54+ , removeDirectoryLink
56+ , getSymbolicLinkTarget
65+ , getModificationTime
67+ , setModificationTime
71+ -- ** Pre-defined directories
73+ , D.XdgDirectoryList(..)
75+ -- ** Existence tests
87+ , D.setOwnerExecutable
88+ , D.setOwnerSearchable
91+import Data.Time (UTCTime)
92+import qualified System.Directory as D
94+import Effectful.Internal.Effect
95+import Effectful.Internal.Monad
97+-- | An effect for interacting with the filesystem.
98+data FileSystem :: Effect where
99+ FileSystem :: FileSystem m r
101+-- | Run the 'FileSystem' effect.
102+runFileSystem :: IOE :> es => Eff (FileSystem : es) a -> Eff es a
103+runFileSystem = evalEffect (IdE FileSystem)
105+----------------------------------------
106+-- Actions on directories
108+-- | Lifted 'D.createDirectory'.
109+createDirectory :: FileSystem :> es => FilePath -> Eff es ()
110+createDirectory = unsafeEff_ . D.createDirectory
112+-- | Lifted 'D.createDirectoryIfMissing'.
113+createDirectoryIfMissing :: FileSystem :> es => Bool -> FilePath -> Eff es ()
114+createDirectoryIfMissing doCreateParents =
115+ unsafeEff_ . D.createDirectoryIfMissing doCreateParents
117+-- | Lifted 'D.removeDirectory'.
118+removeDirectory :: FileSystem :> es => FilePath -> Eff es ()
119+removeDirectory = unsafeEff_ . D.removeDirectory
121+-- | Lifted 'D.removeDirectoryRecursive'.
122+removeDirectoryRecursive :: FileSystem :> es => FilePath -> Eff es ()
123+removeDirectoryRecursive = unsafeEff_ . D.removeDirectoryRecursive
125+-- | Lifted 'D.removePathForcibly'.
126+removePathForcibly :: FileSystem :> es => FilePath -> Eff es ()
127+removePathForcibly = unsafeEff_ . D.removePathForcibly
129+-- | Lifted 'D.renameDirectory'.
130+renameDirectory :: FileSystem :> es => FilePath -> FilePath -> Eff es ()
131+renameDirectory old = unsafeEff_ . D.renameDirectory old
133+-- | Lifted 'D.listDirectory'.
134+listDirectory :: FileSystem :> es => FilePath -> Eff es [FilePath]
135+listDirectory = unsafeEff_ . D.listDirectory
137+-- | Lifted 'D.getDirectoryContents'.
138+getDirectoryContents :: FileSystem :> es => FilePath -> Eff es [FilePath]
139+getDirectoryContents = unsafeEff_ . D.getDirectoryContents
141+----------------------------------------
142+-- Current working directory
144+-- | Lifted 'D.getCurrentDirectory'.
145+getCurrentDirectory :: FileSystem :> es => Eff es FilePath
146+getCurrentDirectory = unsafeEff_ D.getCurrentDirectory
148+-- | Lifted 'D.setCurrentDirectory'.
149+setCurrentDirectory :: FileSystem :> es => FilePath -> Eff es ()
150+setCurrentDirectory = unsafeEff_ . D.setCurrentDirectory
152+-- | Lifted 'D.withCurrentDirectory'.
153+withCurrentDirectory :: FileSystem :> es => FilePath -> Eff es a -> Eff es a
154+withCurrentDirectory path = unsafeLiftMapIO (D.withCurrentDirectory path)
156+----------------------------------------
157+-- Pre-defined directories
159+-- | Lifted 'D.getHomeDirectory'.
160+getHomeDirectory :: FileSystem :> es => Eff es FilePath
161+getHomeDirectory = unsafeEff_ D.getHomeDirectory
163+-- | Lifted 'D.getXdgDirectory'.
169+getXdgDirectory xdgDir = unsafeEff_ . D.getXdgDirectory xdgDir
171+-- | Lifted 'D.getXdgDirectoryList'.
174+ => D.XdgDirectoryList
175+ -> Eff es [FilePath]
176+getXdgDirectoryList = unsafeEff_ . D.getXdgDirectoryList
178+-- | Lifted 'D.getAppUserDataDirectory'.
179+getAppUserDataDirectory :: FileSystem :> es => FilePath -> Eff es FilePath
180+getAppUserDataDirectory = unsafeEff_ . D.getAppUserDataDirectory
182+-- | Lifted 'D.getUserDocumentsDirectory'.
183+getUserDocumentsDirectory :: FileSystem :> es => Eff es FilePath
184+getUserDocumentsDirectory = unsafeEff_ D.getUserDocumentsDirectory
186+-- | Lifted 'D.getTemporaryDirectory'.
187+getTemporaryDirectory :: FileSystem :> es => Eff es FilePath
188+getTemporaryDirectory = unsafeEff_ D.getTemporaryDirectory
190+----------------------------------------
193+-- | Lifted 'D.removeFile'.
194+removeFile :: FileSystem :> es => FilePath -> Eff es ()
195+removeFile = unsafeEff_ . D.removeFile
197+-- | Lifted 'D.renameFile'.
198+renameFile :: FileSystem :> es => FilePath -> FilePath -> Eff es ()
199+renameFile old = unsafeEff_ . D.renameFile old
201+-- | Lifted 'D.renamePath'.
202+renamePath :: FileSystem :> es => FilePath -> FilePath -> Eff es ()
203+renamePath old = unsafeEff_ . D.renamePath old
205+-- | Lifted 'D.copyFile'.
206+copyFile :: FileSystem :> es => FilePath -> FilePath -> Eff es ()
207+copyFile src = unsafeEff_ . D.copyFile src
209+-- | Lifted 'D.copyFileWithMetadata'.
210+copyFileWithMetadata :: FileSystem :> es => FilePath -> FilePath -> Eff es ()
211+copyFileWithMetadata src = unsafeEff_ . D.copyFileWithMetadata src
213+-- | Lifted 'D.getFileSize'.
214+getFileSize :: FileSystem :> es => FilePath -> Eff es Integer
215+getFileSize = unsafeEff_ . D.getFileSize
217+-- | Lifted 'D.canonicalizePath'.
218+canonicalizePath :: FileSystem :> es => FilePath -> Eff es FilePath
219+canonicalizePath = unsafeEff_ . D.canonicalizePath
221+-- | Lifted 'D.makeAbsolute'.
222+makeAbsolute :: FileSystem :> es => FilePath -> Eff es FilePath
223+makeAbsolute = unsafeEff_ . D.makeAbsolute
225+-- | Lifted 'D.makeRelativeToCurrentDirectory'.
226+makeRelativeToCurrentDirectory
230+makeRelativeToCurrentDirectory = unsafeEff_ . D.makeRelativeToCurrentDirectory
232+----------------------------------------
235+-- | Lifted 'D.doesPathExist'.
236+doesPathExist :: FileSystem :> es => FilePath -> Eff es Bool
237+doesPathExist = unsafeEff_ . D.doesPathExist
239+-- | Lifted 'D.doesFileExist'.
240+doesFileExist :: FileSystem :> es => FilePath -> Eff es Bool
241+doesFileExist = unsafeEff_ . D.doesFileExist
243+-- | Lifted 'D.doesDirectoryExist'.
244+doesDirectoryExist :: FileSystem :> es => FilePath -> Eff es Bool
245+doesDirectoryExist = unsafeEff_ . D.doesDirectoryExist
247+-- | Lifted 'D.findExecutable'.
248+findExecutable :: FileSystem :> es => String -> Eff es (Maybe FilePath)
249+findExecutable = unsafeEff_ . D.findExecutable
251+-- | Lifted 'D.findExecutables'.
252+findExecutables :: FileSystem :> es => String -> Eff es [FilePath]
253+findExecutables = unsafeEff_ . D.findExecutables
255+-- | Lifted 'D.findExecutablesInDirectories'.
256+findExecutablesInDirectories
260+ -> Eff es [FilePath]
261+findExecutablesInDirectories dirs =
262+ unsafeEff_ . D.findExecutablesInDirectories dirs
264+-- | Lifted 'D.findFile'.
265+findFile :: FileSystem :> es => [FilePath] -> String -> Eff es (Maybe FilePath)
266+findFile dirs = unsafeEff_ . D.findFile dirs
268+-- | Lifted 'D.findFiles'.
269+findFiles :: FileSystem :> es => [FilePath] -> String -> Eff es [FilePath]
270+findFiles dirs = unsafeEff_ . D.findFiles dirs
272+-- | Lifted 'D.findFileWith'.
275+ => (FilePath -> Eff es Bool)
278+ -> Eff es (Maybe FilePath)
279+findFileWith p dirs n = unsafeEff $ \es -> do
280+ D.findFileWith ((`unEff` es) . p) dirs n
282+-- | Lifted 'D.findFilesWith'.
285+ => (FilePath -> Eff es Bool)
288+ -> Eff es [FilePath]
289+findFilesWith p dirs ns = unsafeEff $ \es -> do
290+ D.findFilesWith ((`unEff` es) . p) dirs ns
292+----------------------------------------
295+-- | Lifted 'D.createFileLink'.
296+createFileLink :: FileSystem :> es => FilePath -> FilePath -> Eff es ()
297+createFileLink target = unsafeEff_ . D.createFileLink target
299+-- | Lifted 'D.createDirectoryLink'.
300+createDirectoryLink :: FileSystem :> es => FilePath -> FilePath -> Eff es ()
301+createDirectoryLink target = unsafeEff_ . D.createDirectoryLink target
303+-- | Lifted 'D.removeDirectoryLink'.
304+removeDirectoryLink :: FileSystem :> es => FilePath -> Eff es ()
305+removeDirectoryLink = unsafeEff_ . D.removeDirectoryLink
307+-- | Lifted 'D.pathIsSymbolicLink'.
308+pathIsSymbolicLink :: FileSystem :> es => FilePath -> Eff es Bool
309+pathIsSymbolicLink = unsafeEff_ . D.pathIsSymbolicLink
311+-- | Lifted 'D.getSymbolicLinkTarget'.
312+getSymbolicLinkTarget :: FileSystem :> es => FilePath -> Eff es FilePath
313+getSymbolicLinkTarget = unsafeEff_ . D.getSymbolicLinkTarget
315+----------------------------------------
318+-- | Lifted 'D.getPermissions'.
319+getPermissions :: FileSystem :> es => FilePath -> Eff es D.Permissions
320+getPermissions = unsafeEff_ . D.getPermissions
322+-- | Lifted 'D.setPermissions'.
323+setPermissions :: FileSystem :> es => FilePath -> D.Permissions -> Eff es ()
324+setPermissions path = unsafeEff_ . D.setPermissions path
326+-- | Lifted 'D.copyPermissions'.
327+copyPermissions :: FileSystem :> es => FilePath -> FilePath -> Eff es ()
328+copyPermissions src = unsafeEff_ . D.copyPermissions src
330+----------------------------------------
333+-- | Lifted 'D.getAccessTime'.
334+getAccessTime :: FileSystem :> es => FilePath -> Eff es UTCTime
335+getAccessTime = unsafeEff_ . D.getAccessTime
337+-- | Lifted 'D.getModificationTime'.
338+getModificationTime :: FileSystem :> es => FilePath -> Eff es UTCTime
339+getModificationTime = unsafeEff_ . D.getModificationTime
341+-- | Lifted 'D.setAccessTime'.
342+setAccessTime :: FileSystem :> es => FilePath -> UTCTime -> Eff es ()
343+setAccessTime path = unsafeEff_ . D.setAccessTime path
345+-- | Lifted 'D.setModificationTime'.
346+setModificationTime :: FileSystem :> es => FilePath -> UTCTime -> Eff es ()
347+setModificationTime path = unsafeEff_ . D.setModificationTime path