This library is in flux. APIs may change without notice. Generated from source with koruc 0.1.7 on 11/4/2026.
FS
import std/fsKoru Standard Library: Filesystem
fs.kz · 10 tors · ~[comptime]· ~[runtime]
Phantom lifecycles
Derived from the phantom labels in the declarations below — state! issues an
obligation the compiler will chase, !state discharges it, a bare state holds it without moving it. Nothing here is hand-drawn.
Dir 1 state open!~[
- aspirational
read-lines exposes a per-line streaming surface but its implementation
SLURPS the whole file into memory (readToEndAlloc), so it is bounded by RAM
and OOMs on inputs larger than memory. The honest fix is true line-by-line
streaming - constant memory, any file size - deferred to a dedicated session.
Marked aspirational so the gap is explicit and greppable, never hidden behind
a clean API. Discipline to close it: a future --allow-aspirational gate flag
plus koruc --list-aspirational. See the no-silent-degradation doctrine.
]pub tor read-lines { path: string }
! line string
| done usize
| failed stringwrite-file
koru_std/fs.kz:77// Write a buffer to a path. The caller's slice is borrowed for the duration
// of the write; the file owns the bytes after `| written`. `| failed` is
// the same loud strings `read-lines` uses on open, plus write-side I/O.
// No cap: the host writes `content` as given. The file is the owner after `| written`.
// Unfenced (cwd-relative) — the fenced spelling is `fs:write` on a `*Dir`.
~pub tor write-file { path: string, content: string }
| written
| failed string~part dir koru_std/fs.dir.kz
DIRECTORY CAPABILITY - *Dir<open> confines every verb to its root fs:dir(path) mints a directory handle; the sandbox IS the handle, not a path-check repeated at every call site. list/read/write/read-lines-in/ collect-lines borrow *Dir<open>; close discharges *Dir<!open>. Every `path:` arg is root-relative — absolute paths and `..` components fire `| failed` here, inside std/fs, so a caller (or a wire model) cannot escape by spelling one. collect-lines materializes the `! line` effect stream as a []string field — the shape a wire consumer sees, since wire arms cannot spell `!`. Wire payloads render it as a JSON array (FieldValue.string_array).
~pub tor dir { path: string }
| opened *Dir<open!>
| failed string~pub tor close { d: *Dir<!open> }// Sorted — a deterministic listing is the honest contract for a dir verb:
// iterate() order is filesystem-dependent and untestable.
~pub tor list { d: *Dir<open> }
| entries []string
| failed string~pub tor read { d: *Dir<open>, path: string }
| text string
| failed string~pub tor write { d: *Dir<open>, path: string, content: string }
| written
| failed string// The effect stream, dir-scoped. Same line semantics as read-lines
// (\r stripped, no trailing-empty line); the buffer lives for the pulse.
~pub tor read-lines-in { d: *Dir<open>, path: string }
! line string
| done usize
| failed string// Materializes the same stream — each line is duped (the buffer frees),
// the marshal owns a second copy for the wire, like every string payload.
~pub tor collect-lines { d: *Dir<open>, path: string }
| lines []string
| failed string~part sync koru_std/fs.sync.kz
SYNC — fsync-grade durability for a path `sync(path)` opens the path and fsyncs it: after `| synced`, the file's bytes are on the device, not in the page cache. A bare `write-file` answers survive-process-death; this answers survive-power-loss — the durability level celld's acknowledged writes carry (SQLite fsync per put).
// SYNC — fsync-grade durability for a path
// `sync(path)` opens the path and fsyncs it: after `| synced`, the file's
// bytes are on the device, not in the page cache. A bare `write-file`
// answers survive-process-death; this answers survive-power-loss — the
// durability level celld's acknowledged writes carry (SQLite fsync per put).
~pub tor sync { path: string }
| synced
| failed string