std/resource

Resource, EmbeddedBytes, EmbeddedText and ResourceError - a file of the package named by a string literal, resolved by the compiler where it is written; a `Resource` is read from beside the program, an `EmbeddedText` from the binary.

Diese Seite gibt es noch nicht auf Deutsch, deshalb steht sie hier auf Englisch. Zur englischen Seite

Die generierte Referenz von std/resource zeigt jede öffentliche Deklaration mit Signatur, Doc-Kommentar und Beispielen.

std/resource names the files a program needs. A string literal where a Resource, an EmbeddedBytes or an EmbeddedText is expected is resolved by the compiler against the file that writes it, and a file that is not there is an error at that line - the literal rule. The value holds the file's stable name: the owner and name of the package, then the path inside it, always with /. The design is docs/design/RESOURCES.md.

A Resource is read while the program runs: torb build copies every file a Resource literal names to <program>.resources/<stable name> beside the binary, and bytes() and text() read it from there - never from the working directory, so the program finds its files wherever it is started from, and a binary that is moved needs its .resources directory with it. EmbeddedText.text() answers the file's text, which the compiler embedded as static data after checking it is UTF-8.

Import#

use Resource, EmbeddedBytes, EmbeddedText, ResourceError from "std/resource"

Declarations#

type Resource with Show, Equals, Hash {
  fn name(): String
  fn bytes(): Task<Result<Bytes, ResourceError>>
  fn text(): Task<Result<String, ResourceError>>
  fn show(): String
}
type EmbeddedBytes with Show, Equals, Hash {
  fn name(): String
  fn show(): String
}
type EmbeddedText with Show, Equals, Hash {
  fn text(): String
  fn name(): String
  fn show(): String
}
type ResourceError with Show, Equals, Error {
  case NotShipped(name: String)
  case Unreadable(name: String, reason: String)
  case NotUtf8(name: String, offset: Int)
  case Unlocated(name: String, reason: String)
  fn show(): String
}
  • A resource literal is relative to the file that writes it, the way a use is: a library's literal names the library's file, whoever calls it.
  • It stays inside its package. "../../secrets/key.pem" is an error that names the package: a file outside it is not published with it and cannot be shipped.
  • It is compared byte for byte, on every platform. "./Hero.png" next to hero.png is an error on Windows and macOS too, where opening the file would have worked, and the message names the file that is there.
  • A String value is never a resource, and cannot be interpolated into one: a path chosen while the program runs is a Path, read through std/fs.
  • Each is a capsule over its stable name, so a literal is the only way to make one.
  • bytes() and text() fail with a ResourceError, never a panic. NotShipped is a binary moved without its .resources directory, Unreadable a file that is there and cannot be read, NotUtf8 is text() of bytes that are no text - it carries the offset of the first bad byte and never a replacement character - and Unlocated a program that cannot tell where its executable is. Every message names the resource by its stable name and no directory of the machine, so it reads the same on every platform and in the VM and in a binary.
  • The returned Task is already complete on a native target, so .await() does not wait. Two literals that reach one file are one resource and one copy in the .resources directory.
  • torb test ships nothing, in the VM and in a binary: a test that reads a Resource sees NotShipped, which is what the std/resource tests assert.
match sheet.text().await() {
  Ok(text) => print text
  Fail(.NotShipped(name)) => print "{name} did not come with this build"
  Fail(problem) => printError "{problem}"
}
Esc