File
4 types7 functionsWhat every file implementation shares: the errors a file operation reports,
the entries a directory lists, and pure functions over /-separated paths.
Nothing here touches a file. A target's file module, such as the wasip2
package's WasiFile, reads and writes them and reports failures in these
types, so code that handles a file error or builds a path is the same on
every target.
Types
Error
Why a file operation failed. A file module reports every failure as
FileErr(path, kind), naming the path its caller passed.
OutsideSandbox is a path no directory the host granted covers, or one that
climbs out of the directory it starts in. A failure with no kind here
arrives as HostError rather than folded into a kind it is not: a host
error with the host's own name for it, or a file module's refusal in words,
such as HostError("not a regular file") for reading a device.
EntryKind
What a directory entry is. OtherEntry is anything else the host has: a
device, a pipe, a socket, or a kind it does not say.
DirEntry
One entry of a directory listing: its name inside the directory, not a path.
Result
Shorthand for [Ok(a) | Err(e)], the variant this module's fallible
functions return.
Functions
join
base and rest with exactly one / between them: join("a/", "/b") is
"a/b". An empty side leaves the other as it is, so join("", "/b") is
"/b". Nothing is normalized, and a .. in rest is kept, so
normalize(join("/static", "../etc/passwd")) is Ok("/etc/passwd"): join
does not keep a path inside base. For a path the caller does not trust,
such as one taken from a request, use within.
within
path, which the caller does not trust, read inside base: path is
normalized as relative to base, so a leading / stands for base itself,
and what is left is joined to base. within("/static", "/a/../b.css") is
Ok("/static/b.css"). A .. that would climb above base is
OutsideSandbox. base is the caller's own and is kept as written; with
nothing left of path the result is base, or "." when base is empty.
normalize
The path with ., empty segments and a trailing / gone, and each ..
cancelling the segment before it: normalize("./a//b/../c/") is "a/c". An
absolute path stays absolute; a path with nothing left is ".", or "/"
when it is absolute.
A .. with nothing left to cancel climbs above where the path starts —
above /, or out of whatever directory a relative path is read in — and is
OutsideSandbox rather than dropped. A .. is cancelled by the text before
it, without asking a host whether that segment is a symbolic link.
baseName
The last segment, ignoring a trailing /: baseName("a/b.txt") is
"b.txt" and baseName("a/b/") is "b". A path with no segment, such as
"/" or "", has the empty base name.
dirName
Every segment but the last, ignoring a trailing /: dirName("a/b.txt") is
"a", dirName("/a") is "/", and a path of one relative segment is in
".".
extension
What follows the last . of the base name, without the dot and as written:
extension("a/b.tar.gz") is "gz". A name with no dot, one that ends in a
dot, or a dot file such as .profile has the empty extension.
contentTypeOf
The content-type to serve a file as, by its extension in any case. A text
type is UTF-8. An extension not in the table is application/octet-stream.