Skip to content
CryoCryo home

path

import std::fs::path; · source

Both Path and PathBuf are length-typed UTF-8 byte sequences with no NUL terminator. Path borrows; PathBuf owns. Crossing into libc goes through a NUL-terminated String built with String::with_null, or PathBuf::into_raw, which hands the buffer over with a terminator appended.

Path syntax is per-target. On Unix / separates and a leading / means absolute — the whole path is one flat sequence of segments. On Windows both / and \ separate, and a path may open with a root that is not a segment and must never be split off or reordered:

C:\dir\file        drive-absolute   root `C:\`
C:dir              drive-relative   root `C:`, resolved against that drive's own cwd
\\server\share     UNC

Types

Path

type struct Path {
    inner: Str;

    static from(source: Str) -> Path;
    as_str(&this) -> Str;
    length(&this) -> u64;
    is_empty(&this) -> boolean;
    static is_separator(byte: u8) -> boolean;
    static byte_or_zero(source: Str, index: u64) -> u8;
    static is_drive_letter(byte: u8) -> boolean;
    static root_len(source: Str) -> u64;
    static is_absolute_str(source: Str) -> boolean;
    static last_separator(source: Str, floor: u64) -> i64;
    static last_dot(name: Str) -> i64;
    is_absolute(&this) -> boolean;
    file_name(&this) -> Option<Str>;
    parent(&this) -> Option<Path>;
    extension(&this) -> Option<Str>;
    join(&this, segment: Str) -> PathBuf;
}

root_len, is_separator, and is_absolute_str are the target-aware primitives the methods are built on, exposed for code that has a Str in hand and no reason to wrap it.

file_name and parent are purely lexical — they never consult the filesystem — and both return None for an empty path or a bare root, where a rooted path's parent yields the root itself, never "". join appends to a copy as a PathBuf, leaving the borrowed path untouched.

extension() consults only the file name, so a dot in a directory component cannot leak in:

foo.rs      -> Some("rs")
foo.tar.gz  -> Some("gz")      last dot only
foo.        -> Some("")        trailing dot, empty extension
foo         -> None            no dot
.bashrc     -> None            a leading dot is not an extension
..          -> None
a/b         -> None            ends in a directory

A leading dot only disqualifies when it is the only dot — .foo.rs still has extension rs.

Properties

PropertyType
innerStr

Constructors

static from(source: Str) -> Path;

Borrow a Str as a Path. A NUL-terminated string (C-string / i8*) converts implicitly at the call site via Str's ![implicit] new, so Path::from("/tmp") and Path::from(some_str) both work; a C-string's terminating NUL is not part of the path bytes. The borrowed bytes must outlive the Path.

Static functions

static is_separator(byte: u8) -> boolean;

Whether byte separates segments on this target.

static byte_or_zero(source: Str, index: u64) -> u8;

source's byte at index, or 0 when out of range. Path syntax never gives 0 a meaning, so callers can compare it without unwrapping.

static is_drive_letter(byte: u8) -> boolean;
static root_len(source: Str) -> u64;

Length of source's leading root, including its trailing separator when one is present; 0 when the path is fully relative.

static is_absolute_str(source: Str) -> boolean;

Whether source resolves without reference to a working DIRECTORY.

static last_separator(source: Str, floor: u64) -> i64;

Index of the last separator at or after floor, or -1 when there is none. Searching from floor is what keeps the root's own separators from being mistaken for segment breaks. Signed so "none" stays distinct from "found at floor" - both are reachable, and conflating them is what makes a root look like an ordinary segment.

static last_dot(name: Str) -> i64;

Index of the last . in name, or -1 when there is none. name is a single path component, not a whole path, so this never has to skip a root or separators - the caller passes the output of file_name.

Methods

as_str(&this) -> Str;
length(&this) -> u64;
is_empty(&this) -> boolean;
is_absolute(&this) -> boolean;

Whether this path is absolute; see is_absolute_str.

file_name(&this) -> Option<Str>;

Last path segment, or None if the path ends with a separator, is empty, or is nothing but a root. Does not consult the filesystem.

parent(&this) -> Option<Path>;

Path minus its final segment, or None if there is no parent - a single relative segment, a bare root, or empty. A rooted path whose last segment is stripped yields the root itself, never "".

extension(&this) -> Option<Str>;

Extension of the final component: the bytes after its last ., or None. It consults only the file name - parent().extension() cannot leak in a dot from a directory:

join(&this, segment: Str) -> PathBuf;

Append segment to a COPY of this path, leaving the borrowed path untouched. The non-mutating twin of PathBuf::push, and it inherits push's root semantics: a segment carrying its own root - /etc, C:\dir, \\server\share - replaces rather than extends: join("/etc") is /etc whatever the path was.

PathBuf<A>

type struct PathBuf<A = GlobalAlloc> {
    inner: String<A>;

    static new() -> PathBuf;
    static from(source: Str) -> PathBuf;
    as_path(&this) -> Path;
    length(&this) -> u64;
    is_empty(&this) -> boolean;
    push(mut &this, segment: Str) -> void;
    pop(mut &this) -> boolean;
    join(&this, segment: Str) -> PathBuf;
    extension(&this) -> Option<Str>;
    into_raw(mut this) -> string;
}

push and join share their root semantics: a segment carrying its own root — /etc, C:\dir, \\server\share — replaces rather than extends. pop removes the last segment and returns whether anything was removed.

Properties

PropertyType
innerString<A>

Constructors

static new() -> PathBuf;
static from(source: Str) -> PathBuf;

Own a copy of a Str (or, implicitly, a NUL-terminated string via Str's ![implicit] new). The bytes are copied into the owned buffer, so source need not outlive the result.

Methods

as_path(&this) -> Path;
length(&this) -> u64;
is_empty(&this) -> boolean;
push(mut &this, segment: Str) -> void;

Append segment, inserting a separator if needed. A segment carrying a root of its own - /etc, C:\dir, \dir, \\server\share - replaces the current path rather than extending it, since appending one path's root inside another would name nothing.

pop(mut &this) -> boolean;

Remove the last segment. Returns true if anything was popped; false at a bare root or an empty path, so this cannot climb out of the volume the path names.

join(&this, segment: Str) -> PathBuf;

Append segment to a COPY of this path and return it, leaving self intact. push mutates in place; join is the owning, non-mutating twin. Same root semantics as push (a rooted segment replaces).

extension(&this) -> Option<Str>;

Extension of the final component; see Path::extension.

into_raw(mut this) -> string;

Consume the PathBuf and return its bytes as an owned, NUL-terminated raw string, leaking the allocation so the caller owns it with no borrow lifetime. Mirrors String::into_raw for handing an owned C-string across the raw-string boundary.

Trait implementations

implement<A> trait Drop for struct PathBuf<A> where A: Allocator

Path is a borrowed view and has nothing to drop.

Constants

const SEPARATOR: u8 = 0x2F;
const BACKSLASH: u8 = 0x5C;
const COLON:     u8 = 0x3A;
const DOT:       u8 = 0x2E;

![target(windows)]
const WINDOWS_SYNTAX: boolean = true;

![target(unix)]
const WINDOWS_SYNTAX: boolean = false;