Library

std/path

Filesystem path manipulation.

1 file lib/std/path/path.vader 18 exports

Paths are immutable string-backed values. Every operation returns a fresh Path rather than mutating. POSIX-style / separator only in MVP: Windows support deferred (will replace the constant with a runtime-determined value).

Types

Path :: string

An immutable filesystem path: a nominal newtype over string. Zero-cost: at runtime a Path is its UTF-8 string, with no wrapper box. Nominal at typecheck so a Path never silently mixes with a raw string ; every combinator returns a fresh Path rather than mutating in place.

Implements Div<string> div :: fn(self, other: string) -> Path
Basename :: struct

The two halves of a filename, as returned by basename.

RETAINED against its own redundancy: filename() / name() / extension() cover every use, and this should have gone with them, but removing it makes vader test lib/std/path panic in to_posix, a function it never touched (no field replace_chars_where on Path). Bisected: ADDING the three views is fine, REMOVING this is what breaks, so it is a materialisation bug the removal merely exposes. tests/vader_e2e.test.ts runs that isolated mode per stdlib module, so the panic is CI-visible. See TODO.md; delete this once fixed.

Fields

name: string

The filename without its final extension: "archive.tar".

extension: string

The final extension without the leading dot: "gz".

Functions

to_posix :: fn(s: string) -> string

Rewrite OS-native path separators to the canonical /. The compiler keeps / as its single internal separator (module discovery, the module index, and vader/front/resolver::join_path are all /-based) so a path entering from an OS boundary that may carry \ (Windows CLI arguments, env vars) must be funnelled through here first, otherwise parent / filename (which split on SEP) silently return empty. POSIX paths pass through unchanged. Takes and returns a raw string, not a Path: the compiler internals it serves (vader/front/resolver::loader, vader/tools/lsp/protocol::uri) are string-based, and the CLI-side Path conversion stops at their boundary. Nothing technical forces this any more: a Path -> Path signature used to panic in midir on the chained cast inside, which is fixed: it is scope.

Parameters

sstring a path string, possibly using \ separators.

Returns

string the same path with every \ rewritten to /.
to_path :: fn(s: string) -> Path

Wrap an existing string as a Path. No validation: assumes the caller has produced a syntactically valid path.

Parameters

sstring the path string.

Returns

empty_path :: fn() -> Path

The empty path (""). Useful as an identity for join / as a default.

Returns

as_string :: fn(self: Path) -> string

Return the underlying string representation. Inverse of to_path.

Parameters

selfPath No description.

Returns

string
is_absolute :: fn(self: Path) -> bool

True iff the path starts with the separator (/foo). Empty paths are considered NOT absolute.

Parameters

selfPath No description.

Returns

bool
parent :: fn(self: Path) -> Path

Parent directory: everything before the last separator. Returns the empty path when there's no separator, or / when the path is at the filesystem root.

Parameters

selfPath the path receiver.

Returns

Path the parent path.
filename :: fn(self: Path) -> string

Last segment (filename or directory name). For a path with no separator, returns the whole path's string.

Parameters

selfPath the path receiver.

Returns

string the filename string (no leading separator).
basename :: fn(self: Path) -> Basename

Both halves of the final segment at once. Prefer name() / extension().

Parameters

selfPath the path receiver.

Returns

Basename { name, extension }, split at the last dot of the filename.
name :: fn(self: Path) -> string

The final segment without its extension.

One of three views on the last segment, none of them overlapping: filename() gives toto.zip, name() gives toto, extension() gives zip.

Parameters

selfPath the path receiver.

Returns

string the filename with its extension and dot removed, or the filename unchanged when it has no extension: a dotfile keeps its full name (.gitignore → .gitignore), since its leading dot is not an extension separator.

Example

"src/archive.tar.gz".to_path().name()  // "archive.tar"
"dir/.gitignore".to_path().name()      // ".gitignore"
extension :: fn(self: Path) -> string

The final segment's extension, without the dot.

One of three views on the last segment, none of them overlapping: filename() gives toto.zip, name() gives toto, extension() gives zip. Kept separate rather than returning both halves at once, so a caller wanting one doesn't pay for the other being built.

Parameters

selfPath the path receiver.

Returns

string the extension without its dot, or "" when the final segment has none: a dotfile and a trailing dot both count as none.

Example

"src/archive.tar.gz".to_path().extension()  // "gz"
"dir/.gitignore".to_path().extension()      // ""
join :: fn(self: Path, other: string) -> Path

Append a sub-path. Adds a separator between segments unless one is already present. If other is absolute (starts with /), it REPLACES self (Java Path.resolve semantics).

Parameters

selfPath the base path.
otherstring the segment to append (may itself contain separators).

Returns

Path a fresh Path.
starts_with :: fn(self: Path, prefix: Path) -> bool

True when self starts with prefix on a segment boundary, so /foo/bar starts with /foo but /foobar does NOT. Useful for "is this under that directory" checks.

Parameters

selfPath the path receiver.
prefixPath the candidate prefix path.

Returns

bool
ends_with :: fn(self: Path, suffix: Path) -> bool

True when self ends with suffix on a segment boundary. Same segment-aware rule as starts_with.

Parameters

selfPath the path receiver.
suffixPath the candidate suffix path.

Returns

bool
normalize :: fn(self: Path) -> Path

Collapse . and .. segments. Purely lexical: does NOT touch the filesystem (no symlink resolution, no existence check). Preserves an absolute prefix when present.

Parameters

selfPath the path receiver.

Returns

Path a fresh, lexically-normalised Path.

Example

"a/./b".to_path().normalize()     // "a/b"
"a/b/..".to_path().normalize()    // "a"
"/a/../b".to_path().normalize()   // "/b"
"../foo".to_path().normalize()    // "../foo"

Constants

SEP

const type inferred path.vader:15
SEP: char :: '/'

Path separator codepoint. POSIX-only in MVP (/).

SEP_STR

const type inferred path.vader:17
SEP_STR: string :: "/"

Path separator as a string: useful for direct concatenation.

Written by vader doc. Icons: Codicons, CC BY 4.0. Fonts: Atkinson Hyperlegible, JetBrains Mono, OFL.