Skip to content
Menu
Contents

Reading the tags

pure

Same arguments, same result; touches nothing outside.

pure if arg2 is

Pure when that argument is a pure function; otherwise as impure as it is.

impure

Reads or changes something outside the program.

File

4 types7 functions

What 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.

At a glance

  • Error

    Why a file operation failed.

  • EntryKind

    What a directory entry is.

  • 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.

  • join

    base and rest with exactly one / between them: join("a/", "/b") is "a/b".

  • 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.

  • normalize

    The path with ., empty segments and a trailing / gone, and each .. cancelling the segment before it: normalize("./a//b/../c/") is "a/c".

  • baseName

    The last segment, ignoring a trailing /: baseName("a/b.txt") is "b.txt" and baseName("a/b/") is "b".

  • 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".

  • contentTypeOf

    The content-type to serve a file as, by its extension in any case.

Types

Error

Error = [
  NotFound
  | PermissionDenied
  | AlreadyExists
  | IsDirectory
  | NotDirectory
  | NotEmpty
  | OutsideSandbox
  | HostError(String)
]

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

EntryKind = [RegularFile | Directory | SymbolicLink | OtherEntry]

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

DirEntry = { name: String, kind: EntryKind }

One entry of a directory listing: its name inside the directory, not a path.

Result

Result(a, e) = [Ok(a) | Err(e)]

Shorthand for [Ok(a) | Err(e)], the variant this module's fallible functions return.

Functions

join

(String, String) -> Stringpure

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

(String, String) -> Result(String, [OutsideSandbox | e])pure

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

(String) -> Result(String, [OutsideSandbox | e])pure

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

(String) -> Stringpure

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

(String) -> Stringpure

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

(String) -> Stringpure

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

(String) -> Stringpure

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.

Reading the tags

pure

Same arguments, same result; touches nothing outside.

pure if arg2 is

Pure when that argument is a pure function; otherwise as impure as it is.

impure

Reads or changes something outside the program.