never executed always true always false
    1 module PureClaw.Handles.File
    2   ( -- * Handle type
    3     FileHandle (..)
    4     -- * Implementations
    5   , mkFileHandle
    6   , mkNoOpFileHandle
    7   ) where
    8 
    9 import Data.ByteString (ByteString)
   10 import Data.ByteString qualified as BS
   11 import Data.Either
   12 import System.Directory
   13 import System.FilePath
   14 
   15 import PureClaw.Core.Types
   16 import PureClaw.Security.Path
   17 
   18 -- | File system capability. Functions that only receive a 'FileHandle'
   19 -- cannot shell out or access the network — they can only read and write
   20 -- files within the workspace.
   21 --
   22 -- All operations require a 'SafePath', which guarantees the path has been
   23 -- validated against the workspace root and blocked-path list.
   24 data FileHandle = FileHandle
   25   { _fh_readFile  :: SafePath -> IO ByteString
   26   , _fh_writeFile :: SafePath -> ByteString -> IO ()
   27   , _fh_listDir   :: SafePath -> IO [SafePath]
   28   }
   29 
   30 -- | Real file handle that performs actual filesystem operations.
   31 -- 'listDir' validates each child entry through 'mkSafePath', filtering
   32 -- out any blocked paths (e.g. @.env@).
   33 mkFileHandle :: WorkspaceRoot -> FileHandle
   34 mkFileHandle root = FileHandle
   35   { _fh_readFile  = BS.readFile . getSafePath
   36   , _fh_writeFile = BS.writeFile . getSafePath
   37   , _fh_listDir   = \sp -> do
   38       let dir = getSafePath sp
   39       entries <- listDirectory dir
   40       results <- mapM (mkSafePath root . (dir </>)) entries
   41       pure (rights results)
   42   }
   43 
   44 -- | No-op file handle. Read returns empty, write is silent, list returns empty.
   45 mkNoOpFileHandle :: FileHandle
   46 mkNoOpFileHandle = FileHandle
   47   { _fh_readFile  = \_ -> pure BS.empty
   48   , _fh_writeFile = \_ _ -> pure ()
   49   , _fh_listDir   = \_ -> pure []
   50   }