Fs.FileSystem
eff FileSystemSourceAn effect used to perform all filesystem operations.
Operations
def accessTime(f: String): Result[IoError, Int64] \ FileSystem
SourceReturns the last access time of the given file f in milliseconds since the epoch.
def append(data: { str = String }, f: String): Result[IoError, Unit] \ FileSystem
SourceAppends str to the given file f.
Creates the file f if it does not exist.
def appendBytes(data: Vector[Int8], f: String): Result[IoError, Unit] \ FileSystem
SourceAppends data to the given file f.
Creates the file f if it does not exist.
def appendLines(data: { lines = List[String] }, f: String): Result[IoError, Unit] \ FileSystem
SourceAppends lines to the given file f.
Creates the file f if it does not exist.
def copyWith(src: { src = String }, dst: String, opts: Set[CopyOption]): Result[IoError, Unit] \ FileSystem
SourceCopies the file src to dst with the given options.
def creationTime(f: String): Result[IoError, Int64] \ FileSystem
SourceReturns the creation time of the given file f in milliseconds since the epoch.
def delete(f: String): Result[IoError, Unit] \ FileSystem
SourceDeletes the given file f.
Fails if the file does not exist.
def exists(f: String): Result[IoError, Bool] \ FileSystem
SourceReturns true if the given file f exists.
def glob(base: String, pattern: String): Result[IoError, List[String]] \ FileSystem
SourceReturns a list of paths under base that match the given glob pattern.
def isDirectory(f: String): Result[IoError, Bool] \ FileSystem
SourceReturns true if the given file f is a directory.
def isExecutable(f: String): Result[IoError, Bool] \ FileSystem
SourceReturns true if the given file f is executable.
def isReadable(f: String): Result[IoError, Bool] \ FileSystem
SourceReturns true if the given file f is readable.
def isRegularFile(f: String): Result[IoError, Bool] \ FileSystem
SourceReturns true if the given file f is a regular file.
def isSymbolicLink(f: String): Result[IoError, Bool] \ FileSystem
SourceReturns true if the given file f is a symbolic link.
def isWritable(f: String): Result[IoError, Bool] \ FileSystem
SourceReturns true if the given file f is writable.
def list(f: String): Result[IoError, List[String]] \ FileSystem
SourceReturns a list with the names of all files and directories in the given directory f.
def mkDir(d: String): Result[IoError, Unit] \ FileSystem
SourceCreates the directory d.
def mkDirs(d: String): Result[IoError, Unit] \ FileSystem
SourceCreates the directory d and all its parent directories.
def mkTempDir(prefix: String): Result[IoError, String] \ FileSystem
SourceCreates a new temporary directory with the given prefix.
Returns the path to the directory.
def modificationTime(f: String): Result[IoError, Int64] \ FileSystem
SourceReturns the last-modified timestamp of the given file f in milliseconds since the epoch.
def moveWith(src: { src = String }, dst: String, opts: Set[MoveOption]): Result[IoError, Unit] \ FileSystem
SourceMoves (renames) the file or directory src to dst with the given options.
def read(f: String): Result[IoError, String] \ FileSystem
SourceReturns a string of all the contents of the given file f.
def readBytes(f: String): Result[IoError, Vector[Int8]] \ FileSystem
SourceReturns a vector of all the bytes in the given file f.
def readLines(f: String): Result[IoError, List[String]] \ FileSystem
SourceReturns a list of all lines in the given file f.
def size(f: String): Result[IoError, Size] \ FileSystem
SourceReturns the size of the given file f.
def truncate(f: String): Result[IoError, Unit] \ FileSystem
SourceTruncates the given file f.
def write(data: { str = String }, f: String): Result[IoError, Unit] \ FileSystem
SourceWrites str to the given file f.
Creates file f if it does not exist. Overwrites it if it exists.
def writeBytes(data: Vector[Int8], f: String): Result[IoError, Unit] \ FileSystem
SourceWrites data to the given file f.
Creates file f if it does not exist. Overwrites it if it exists.
def writeLines(data: { lines = List[String] }, f: String): Result[IoError, Unit] \ FileSystem
SourceWrites lines to the given file f.
Creates f if it does not exist. Overwrites it if it exists.
Definitions
def copy(src: { src = String }, dst: String): Result[IoError, Unit] \ FileSystem
SourceConvenience function: copies src to dst with no options.
def handle(f: a -> b \ ef): a -> b \ (ef - FileSystem) + IO
SourceHandles the FileSystem effect of the given function f.
In other words, re-interprets the FileSystem effect using the IO effect.
def move(src: { src = String }, dst: String): Result[IoError, Unit] \ FileSystem
SourceConvenience function: moves src to dst with no options.
@DefaultHandler def runWithIO(f: Unit -> a \ ef): a \ (ef - FileSystem) + IO
SourceRuns the FileSystem effect of the given function f.
In other words, re-interprets the FileSystem effect using the IO effect.
def withAllowGlob(patterns: Nel[String], f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, validating that all file paths
match at least one of the given glob patterns. Rejects paths that do not match
with a PermissionDenied error.
The mkTempDir operation is blocked since the temp directory location cannot be verified.
def withAllowList(allowedDirs: Nel[String], f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, validating that all file paths
resolve within one of the given allowedDirs. Rejects paths outside the
allow list with a PermissionDenied error.
The mkTempDir operation is blocked since the temp directory location cannot be verified.
def withAtomicWrite(f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, making write,
writeLines, and writeBytes atomic. Data is first written to a
temporary file in the same directory, then atomically moved into place.
On failure the temporary file is cleaned up.
All other operations (read, stat, test, list, glob, append, truncate, copy, move, delete, mkdir) are passed through unchanged.
def withBackup(suffix: String, f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, creating a backup
of existing files before destructive operations. Before write,
writeLines, writeBytes, truncate, and delete, the existing
file is copied to file + suffix (e.g., "data.txt.bak" when
suffix is ".bak").
For copyWith and moveWith, the destination file is backed up.
If the file does not exist, no backup is created and the operation proceeds normally. If the backup fails for any other reason, the original operation is aborted and the backup error is returned.
If a backup file already exists, it is overwritten. Only the most recent previous version of each file is preserved.
Read, stat, test, list, glob, append, mkdir, and mkTempDir operations are passed through unchanged.
def withBaseDir(baseDir: String, f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, resolving all file paths
relative to the given baseDir using Java's Path.resolve semantics.
Absolute paths are passed through unchanged. The mkTempDir prefix is not resolved.
def withChecksum(hash: Vector[Int8] -> Vector[Int8], sidecar: String, f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, providing data integrity
via checksum sidecar files. Write operations produce checksum sidecars;
read operations verify against them.
hash is a pure function from file bytes to digest bytes.
sidecar is the file suffix (e.g., ".sha256").
After write, append, truncate, and copy operations, the file is re-read and a sidecar containing the hex digest is written. After move, the sidecar is moved. After delete, the sidecar is removed.
On read, if a sidecar exists, the file's contents are hashed and compared against the stored checksum. If no sidecar exists, the read proceeds normally.
Stat, test, permission, time, size, list, and glob operations are passed through unchanged.
def withChroot(chrootDir: String, f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, validating that all file paths
resolve within the given chrootDir. Rejects paths that escape the chroot with
a PermissionDenied error.
The mkTempDir operation is blocked since it creates directories outside the chroot.
def withConflictCheck(f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, providing optimistic
concurrency control. When a file is read (read, readLines,
readBytes), its modification time is snapshotted. When a file is
subsequently written, the current modification time is compared against
the snapshot. If the file was modified externally, the operation returns
Err(Conflict(...)).
After a successful write, the modification time is re-snapshotted to prevent false positives on subsequent writes to the same file.
Files that were never read have no snapshot and are written without conflict checks.
The following operations are passed through unchanged:
exists, isDirectory, isRegularFile, isSymbolicLink,
isReadable, isWritable, isExecutable, accessTime,
creationTime, modificationTime, size, list, glob,
mkDir, mkDirs, and mkTempDir.
def withDenyGlob(patterns: Nel[String], f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, validating that all file paths
do not match any of the given glob patterns. Rejects paths that match a denied
pattern with a PermissionDenied error.
The mkTempDir operation is allowed since deny globs are default-allow.
def withDenyList(deniedDirs: Nel[String], f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, validating that all file paths
do not resolve within any of the given deniedDirs. Rejects paths inside a
denied directory with a PermissionDenied error.
The mkTempDir operation is allowed since deny lists are default-allow.
def withDryRun(f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem + Logger
SourceMiddleware that intercepts the FileSystem effect, logging each write
operation via the Logger effect at Debug level without performing
the actual filesystem modification. All write operations return Ok(());
mkTempDir returns Ok("<dry-run>"). Read, stat, and test operations
are passed through to the underlying FileSystem effect unchanged.
def withFollowLinks(f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, resolving all file paths
to their real filesystem targets by following symlinks. This gives opt-in
"follow symlinks" behavior (traditional Unix stat vs lstat semantics).
- Bool ops (
exists,isDirectory, etc.): resolve path; returnOk(false)for dangling symlinks. - Value ops (
accessTime,size, etc.): resolve path; propagate all errors. - Action ops (
read,write, etc.): resolve path with fallback to original (for file creation). isSymbolicLink: passed through unchanged (always checks the link itself).mkTempDir: passed through unchanged (no path to resolve).
def withInMemoryFS(f: Unit -> a \ ef): a \ (ef - FileSystem) + Clock
SourceTerminal handler that intercepts the FileSystem effect with a fully
in-memory filesystem. The filesystem starts empty; reads of non-written
files return NotFound. No real filesystem access occurs. This is
useful for testing, sandboxing, and deterministic simulations.
def withLogging(f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem + Logger
SourceMiddleware that intercepts the FileSystem effect, logging each operation
and its result via the Logger effect.
Successful operations are logged at Debug level; errors at Warn.
def withMemoryOverlay(f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, layering an in-memory
writable store on top of the real filesystem. Writes are captured in memory
(never touching disk), and subsequent reads see the written data. The real
filesystem is never modified. This is useful for safe experimentation,
testing, and sandboxing.
def withMkParentDirs(f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, automatically creating
parent directories before write, append, copy, and move operations.
Before write, writeLines, writeBytes, append, appendLines,
appendBytes, copyWith, and moveWith, the parent directory of the
target file is created via mkDirs. If the parent directory already
exists, this is a no-op.
If parent directory creation fails, the original operation is aborted and the error is returned.
Read, stat, test, list, glob, truncate, delete, mkDir, mkDirs,
and mkTempDir are passed through unchanged.
def withReadOnly(f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, blocking all write
operations with a PermissionDenied error while passing read, stat,
and test operations through to the underlying FileSystem effect
unchanged. This is useful for sandboxing code that should only observe
the filesystem.
def withSizeRotation(maxSize: Size, maxFiles: Int32, f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, automatically rotating
files when they reach a size threshold before append operations.
Before append, appendLines, and appendBytes, the target file's size
is checked. If it meets or exceeds maxSize, existing rotated files are
shifted (file.1 → file.2, etc.), the oldest (file.{maxFiles}) is
deleted, and the current file is moved to file.1. The append then
writes to the now-absent original path.
All other operations are passed through unchanged.
def withTransferLimit(maxSize: Size, f: Unit -> a \ ef): a \ (ef - FileSystem) + FileSystem
SourceMiddleware that intercepts the FileSystem effect, rejecting read, write,
and append operations where the data exceeds maxBytes. For reads and
copyWith, the file size is checked via FileSystem.size.
String-based operations estimate byte count as charCount * 4 (the
maximum bytes per character in UTF-8). Use byte-based operations for
exact enforcement.
Operations that don't transfer data (truncate, moveWith, delete,
mkDir, mkDirs, mkTempDir) and metadata operations are passed
through unchanged.