Module fs/types

fs/types
Stability: unstable — `OpenMode` and `OpenOptions` are two answers to one question and only one of them should survive. `OpenOptions` (new 2026-09-09) is strictly more expressive; `OpenMode` remains the argument type of `File.open`, the spelling every existing caller uses, and the shape whose `.CreateNew` variant does NOT grant read access the way `OpenOptions.create_new(true)` can. Freezing follows a decision on whether `OpenMode` becomes a set of `OpenOptions` constructors (and `File.open` takes `OpenOptions`), not a release count. `OpenOptions.to_flags` also still returns `Result(i32, String)`, which is a D1 violation carried deliberately: the four rejections are programmer mistakes rather than OS failures, and giving them an error enum is pending the same decision. — stable modules only change additively; this one may still change.

File system types for open modes, permissions, and seek positions.

Three small vocabularies that std/fs/file consumes: OpenMode (the five common open recipes) and OpenOptions (the full flag set, for the combinations the enum cannot spell), FilePermission (the POSIX mode a newly created file gets), and SeekFrom (the reference point for File.seek, and the type argument of std/io's Seek(From) trait).

Nothing here performs I/O — these are the values you hand to the calls that do, so every function in this module is a pure, synchronous translation into POSIX flag words.

Stability

unstable — OpenMode and OpenOptions are two answers to one question and only one of them should survive. OpenOptions (new 2026-09-09) is strictly more expressive; OpenMode remains the argument type of File.open, the spelling every existing caller uses, and the shape whose .CreateNew variant does NOT grant read access the way OpenOptions.create_new(true) can. Freezing follows a decision on whether OpenMode becomes a set of OpenOptions constructors (and File.open takes OpenOptions), not a release count.

OpenOptions.to_flags also still returns Result(i32, String), which is a D1 violation carried deliberately: the four rejections are programmer mistakes rather than OS failures, and giving them an error enum is pending the same decision.

Types

OpenMode enum
OpenMode

Determines how a file is opened.

Variants

VariantFieldsDescription
Read

Read an existing file (O_RDONLY).

Write

Create or overwrite a file (O_WRONLY | O_CREAT | O_TRUNC).

Append

Append to a file (O_WRONLY | O_CREAT | O_APPEND).

ReadWrite

Read and write an existing file (O_RDWR).

CreateNew

Create a new file, fail if it already exists (O_WRONLY | O_CREAT | O_EXCL).

FilePermission newtype
FilePermission

POSIX file permission bits.

Fields

NameTypeDescription
modeu32
impl(FilePermission, ...)
default : (FilePermission) fn() -> FilePermission

0o644rw-r--r--. The usual mode for a data file: writable by its owner, readable by everyone. This is what File.open passes when the mode creates a file and the caller named no permission; the process umask still clears bits from it, so a umask of 0o022 is what makes this the effective default rather than the request.

Returns: FilePermission

executable : (FilePermission) fn() -> FilePermission

0o755rwxr-xr-x. default plus the execute bit for everyone: scripts and binaries. Note the execute bit is only meaningful on POSIX; Windows decides executability from the file extension.

Returns: FilePermission

readonly : (FilePermission) fn() -> FilePermission

0o444r--r--r--. Readable by everyone, writable by nobody, which is the state Metadata.is_readonly reports true for. It does not stop root, and it does not stop the file's owner from chmod-ing it back.

Returns: FilePermission

private : (FilePermission) fn() -> FilePermission

0o600rw-------. Owner only: the mode to use for anything holding a credential, and the mode mkstemp (so TempFile) already creates with. Unlike the other three this is not weakened by a typical umask, because no group or other bit is being asked for.

Returns: FilePermission

OpenOptions struct
OpenOptions

A builder for the open flags — Rust's fs::OpenOptions.

OpenMode's five variants are the common combinations, and they cannot express the rest: there is no read+append, no create-without-truncate, no read+write+create. Rather than grow that enum combinatorially, this builds the flag set directly.

A plain value struct with functional setters, so a chain builds a new value at each step and nothing is shared or allocated:

f := io.await(
  File.open_opts(path, OpenOptions.new().read(true).append(true).create(true), io),
  { io, exn }
);

to_flags() resolves the POSIX flag set, and REJECTS the combinations POSIX would silently misinterpret rather than passing them through.

Fields

NameTypeDescription
_readbool
_writebool
_appendbool
_truncatebool
_createbool
_create_newbool
impl(OpenOptions, ...)
new : (OpenOptions) fn() -> OpenOptions

All flags off. At least one of read/write/append must be set before to_flags() will accept it.

Returns: OpenOptions

read : (OpenOptions) fn(self : OpenOptions, on : bool) -> OpenOptions

Open for reading.

Parameters

NameTypeNotes
selfOpenOptions
onbool

Returns: OpenOptions

write : (OpenOptions) fn(self : OpenOptions, on : bool) -> OpenOptions

Open for writing.

Parameters

NameTypeNotes
selfOpenOptions
onbool

Returns: OpenOptions

append : (OpenOptions) fn(self : OpenOptions, on : bool) -> OpenOptions

Every write goes to the END of the file regardless of the seek position (O_APPEND). Grants write access on its own.

Parameters

NameTypeNotes
selfOpenOptions
onbool

Returns: OpenOptions

truncate : (OpenOptions) fn(self : OpenOptions, on : bool) -> OpenOptions

Truncate the file to zero length on open. Needs write access.

Parameters

NameTypeNotes
selfOpenOptions
onbool

Returns: OpenOptions

create : (OpenOptions) fn(self : OpenOptions, on : bool) -> OpenOptions

Create the file if it does not exist. Needs write or append access.

Parameters

NameTypeNotes
selfOpenOptions
onbool

Returns: OpenOptions

create_new : (OpenOptions) fn(self : OpenOptions, on : bool) -> OpenOptions

Create the file, failing if it ALREADY exists. Implies create, and the check-and-create is atomic (O_EXCL), which is what makes it usable as a lock.

Parameters

NameTypeNotes
selfOpenOptions
onbool

Returns: OpenOptions

creates : (OpenOptions) fn(self : OpenOptions) -> bool

True when this combination can create the file, so the caller knows whether the permission argument is consulted.

Parameters

NameTypeNotes
selfOpenOptions

Returns: bool

to_flags : (OpenOptions) fn(self : OpenOptions) -> Result(i32, String)

The POSIX flag set, or .Err naming the contradiction.

The rejected combinations are the ones POSIX does NOT diagnose — it quietly ignores whichever flag does not apply, handing back a file that behaves differently from what was asked:

  • nothing to do: no read, write or append.
  • truncate without write access: O_TRUNC with O_RDONLY is undefined by POSIX and a no-op on Linux.
  • truncate with append: contradictory — append means every write goes to the end, truncate means the end is zero.
  • create without write access: there is nothing to create the file for.

Parameters

NameTypeNotes
selfOpenOptions

Returns: Result(i32, String)

SeekFrom enum
SeekFrom

Reference point for file seek operations.

Variants

VariantFieldsDescription
Start

Seek from the beginning of the file.

Current

Seek relative to the current position.

End

Seek relative to the end of the file.

Functions

fn(mode : OpenMode) -> i32

Parameters

NameTypeNotes
modeOpenMode

Returns: i32

fn(mode : OpenMode) -> bool

Parameters

NameTypeNotes
modeOpenMode

Returns: bool

fn(from : SeekFrom) -> i32

Parameters

NameTypeNotes
fromSeekFrom

Returns: i32