Skip to main content

Module storage

Module storage 

Source
Expand description

Named values only this application reads and writes, kept until the next run.

A task list, a draft, a setting: state an application has to find again after it restarts, and that the user does not expect to see in a file manager. Files the user picked are something else, and go through the file dialog.

The same code runs everywhere, and every operation is a future, because the browser has no synchronous storage the page can wait on:

ⓘ
scope.launch(async move {
    let saved = storage::read_string("tasks.tsv").await;
    // ...
    storage::write("tasks.tsv", text).await?;
});

Where the values live:

  • macOS and iOS: $HOME/Library/Application Support/<identifier>/storage/<key>;
  • Linux: $XDG_DATA_HOME/<identifier>/storage/<key>, or ~/.local/share/<identifier>/storage/<key> without it;
  • Windows: %APPDATA%\<identifier>\storage\<key>;
  • Android: <files directory>/compose-rust/storage/<key>, the directory the Renderer reports at start, because only a Context knows it;
  • the web: the IndexedDB database compose-rust/<identifier>, store values.

COMPOSE_RUST_STORAGE_DIR, when set, replaces the whole .../storage directory on every platform but the web, so a test or a development run never touches the user’s real data.

On the native platforms the files are read and written by one storage thread of the Host’s, never on the UI thread, and a write goes to a temporary file in the same directory that replaces the old one with a rename, so a crash leaves the old value or the new one and never half of either. On the web the Renderer does the work in the browser and answers each request with one event.

Each application has its own storage, named by the identifier it gives LaunchBuilder::identifier. An application that gives none has no storage: every operation answers StorageError::Unavailable and says so. The identifier is never guessed from a bundle, a package name or an executable name, because the same program would then see different storage depending on how it was started.

Enums§

StorageError
Why a storage operation did not do what it was asked.

Constants§

MAX_IDENTIFIER_BYTES
The longest application identifier, in bytes.
MAX_KEY_BYTES
The longest key, in bytes.
MAX_VALUE_BYTES
The largest value one key holds, in bytes.
STORAGE_DIR_ENV
The environment variable that replaces the storage directory on the native platforms.
WEB_ANSWER_LIMIT
The most bytes one answer can carry back from the web Renderer: the largest event buffer the Host lends it, less the answer’s own record. That is more than MAX_VALUE_BYTES, so every value a write accepted reads back; a larger one, which only another writer to the same browser storage could have left, is reported as too large rather than cut short.

Functions§

identifier
The identifier the application launched with, if it gave one.
is_valid_key
Whether key follows the rules for a key: 1 to MAX_KEY_BYTES bytes of lower case ASCII letters, digits, -, _ and ., not starting with ..
keys
Every key this application has stored a value under, in byte order.
read
Reads the value stored under key. Ok(None) when there is none, which is what the first run of an application finds.
read_string
read for a value that is text. StorageError::NotUtf8 when it is not.
remove
Removes the value stored under key. Removing a key that holds nothing succeeds.
validate_identifier
Checks an application identifier: 1 to MAX_IDENTIFIER_BYTES bytes of ASCII letters, digits, . and -. It names a directory and a database as it is, so nothing else is allowed. The error says what is wrong with it.
write
Stores value under key, replacing what was there.