flix

0.69.3

Fs.FileWrite

eff FileWriteSource

An effect used to write files, append to files, truncate files, and create directories.

Operations

def append(data: { str = String }, f: String): Result[IoError, Unit] \ FileWrite Source

Appends 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] \ FileWrite Source

Appends 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] \ FileWrite Source

Appends 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] \ FileWrite Source

Copies the file src to dst with the given options.

def delete(f: String): Result[IoError, Unit] \ FileWrite Source

Deletes the given file f.

Fails if the file does not exist.

def mkDir(d: String): Result[IoError, Unit] \ FileWrite Source

Creates the directory d.

def mkDirs(d: String): Result[IoError, Unit] \ FileWrite Source

Creates the directory d and all its parent directories.

def mkTempDir(prefix: String): Result[IoError, String] \ FileWrite Source

Creates a new temporary directory with the given prefix.

Returns the path to the directory.

def moveWith(src: { src = String }, dst: String, opts: Set[MoveOption]): Result[IoError, Unit] \ FileWrite Source

Moves (renames) the file or directory src to dst with the given options.

def truncate(f: String): Result[IoError, Unit] \ FileWrite Source

Truncates the given file f.

def write(data: { str = String }, f: String): Result[IoError, Unit] \ FileWrite Source

Writes 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] \ FileWrite Source

Writes 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] \ FileWrite Source

Writes 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] \ FileWrite Source

Convenience function: copies src to dst with no options.

def handle(f: a -> b \ ef): a -> b \ (ef - FileWrite) + IO Source

Handles the FileWrite effect of the given function f.

In other words, re-interprets the FileWrite effect using the IO effect.

def move(src: { src = String }, dst: String): Result[IoError, Unit] \ FileWrite Source

Convenience function: moves src to dst with no options.

def runWithFileSystem(f: Unit -> a \ ef): a \ (ef - FileWrite) + FileSystem Source

Handles the FileWrite effect of the given function f using the FileSystem effect.

@DefaultHandler
def runWithIO(f: Unit -> a \ ef): a \ (ef - FileWrite) + IO Source

Runs the FileWrite effect of the given function f.

In other words, re-interprets the FileWrite effect using the IO effect.

def withAllowGlob(patterns: Nel[String], f: Unit -> a \ ef): a \ (ef - FileWrite) + FileWrite Source

Middleware that intercepts the FileWrite 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 - FileWrite) + FileWrite Source

Middleware that intercepts the FileWrite 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 - FileWrite) + FileWrite Source

Middleware that intercepts the FileWrite 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 (append, truncate, copy, move, delete, mkdir) are passed through unchanged.

def withBackup(suffix: String, f: Unit -> a \ ef): a \ (ef - FileWrite) + FileWrite Source

Middleware that intercepts the FileWrite 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.

Append, mkdir, and mkTempDir operations are passed through unchanged.

def withBaseDir(baseDir: String, f: Unit -> a \ ef): a \ (ef - FileWrite) + FileWrite Source

Middleware that intercepts the FileWrite 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 - FileWrite) + FileWrite + FileRead Source

Middleware that intercepts the FileWrite effect, computing checksums after write operations and storing them as sidecar files.

hash is a pure function from file bytes to digest bytes. sidecar is the file suffix (e.g., ".sha256").

After write, writeLines, writeBytes, append, appendLines, appendBytes, truncate, and copyWith, the file is re-read and its checksum sidecar is updated.

After moveWith, the source's sidecar is moved to the destination path. After delete, the sidecar file is also removed.

mkDir, mkDirs, and mkTempDir are passed through unchanged.

def withChroot(chrootDir: String, f: Unit -> a \ ef): a \ (ef - FileWrite) + FileWrite Source

Middleware that intercepts the FileWrite 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 - FileWrite) + FileWrite + FileStat Source

Middleware that intercepts the FileWrite effect, tracking file modification times across writes and checking for external modifications before each write.

Before write, writeLines, writeBytes, append, appendLines, appendBytes, and truncate, the file's current modification time is compared against the last recorded snapshot. If they differ, a Conflict error is returned. After a successful write, the modification time is re-snapshotted for subsequent checks.

For copyWith and moveWith, the conflict check is applied to the destination path.

After delete, the snapshot for that file is removed.

mkDir, mkDirs, and mkTempDir are passed through unchanged.

Note: Unlike the FileSystem version, this middleware does not snapshot on read operations. Conflict detection begins after the first write to each file, catching write-write conflicts from external processes.

def withDenyGlob(patterns: Nel[String], f: Unit -> a \ ef): a \ (ef - FileWrite) + FileWrite Source

Middleware that intercepts the FileWrite 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 - FileWrite) + FileWrite Source

Middleware that intercepts the FileWrite 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 - FileWrite) + Logger Source

Middleware that intercepts the FileWrite 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>").

def withLogging(f: Unit -> a \ ef): a \ (ef - FileWrite) + FileWrite + Logger Source

Middleware that intercepts the FileWrite effect, logging each operation and its result via the Logger effect.

Successful operations are logged at Debug level; errors at Warn.

def withMkParentDirs(f: Unit -> a \ ef): a \ (ef - FileWrite) + FileWrite Source

Middleware that intercepts the FileWrite 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.

truncate, delete, mkDir, mkDirs, and mkTempDir are passed through unchanged.

def withReadOnly(f: Unit -> a \ ef): a \ ef - FileWrite Source

Middleware that intercepts the FileWrite effect, blocking all write operations with a PermissionDenied error. This is useful for sandboxing code that should only observe the filesystem.

def withSizeRotation(maxSize: Size, maxFiles: Int32, f: Unit -> a \ ef): a \ (ef - FileWrite) + FileWrite + FileStat Source

Middleware that intercepts the FileWrite 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 via FileStat.size. If it meets or exceeds maxSize, existing rotated files are shifted (file.1file.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 - FileWrite) + FileWrite + FileStat Source

Middleware that intercepts the FileWrite effect, rejecting write and append operations where the payload exceeds maxBytes. For copyWith, the source file size is checked via FileStat.size.

String-based operations estimate byte count as charCount * 4 (the maximum bytes per character in UTF-8). Use writeBytes/appendBytes for exact enforcement.

Operations that don't transfer data (truncate, moveWith, delete, mkDir, mkDirs, mkTempDir) are passed through unchanged.