# Platform Notes

> UStore for Rust

### What This Crate Does Not Expose

These C entry points also take a deferred completion, but the crate calls them blocking, whatever receiver you hold:

- `ustore_database_init_ram`, `ustore_database_view_rocksdb` and the `ustore_database_open_*` family, whose options name the executor the open runs on.
- `ustore_database_describe` and `ustore_collection_create`.
- `ustore_transaction_init` for a new transaction, and `ustore_snapshot_init`.
- `ustore_blobs_cursor_next`, which runs on the executor of the view that opened the cursor, and opens only from a blocking one.

Every call through a `Collection`, and `Executor::drain`, block as well.

The crate binds none of these:

- The strings cursor, which `export_arrow` drives, and the range removals of `ustore_pages_remove`.
- The progress of a cursor pull, which reports a single unit once its page is out.
- The lengths a read writes beside its values, which the tape's offsets already carry.

### Design

The crate is a thin layer over the C ABI in `c/ustore/`, and every rule below follows from that.

- __Verbs are named as in C.__
  A C verb drops only what its receiver already names, so `ustore_docs_write` is `docs_write` on a view and `ustore_collection_find` is `collection_find`, while the blob verbs, which reach documents as well, keep their bare names.
  The constructors keep C's lifecycle names: `init_ram` starts empty, `open_<engine>` serves a directory in place, and `view_rocksdb` serves one read-only.
- __Blocking verbs return `Result` directly.__
  `database.head().read(people, &[ada, grace], &mut arena)?` takes no executor, completion or call value, and nothing about asynchrony reaches a caller who never asks for it.
- __`On<'view, Parent, Completion>` makes the receiver a type, not a flag.__
  What every C argument struct puts before its inputs, the view, the executor and the completion, is chosen by the receiver a verb is called on: `database.head()`, `transaction.view(watch)` or `snapshot.view()`, then `.on(&executor)` or `.deferred(&executor)`, where `transaction.on(&executor)` and `transaction.deferred(&executor)` watch the keys.
  Each verb is written once, generic over the completion, so a `DeferredOn` offers the same verbs with the same arguments and answers a `Deferred` instead of the result.
  Opening a database has no view yet, so its options name the executor, and the open blocks.
- __A call the view cannot serve does not compile.__
  The parent, a `Database`, a `Transaction` or a `Snapshot`, decides the verbs beyond the reads: only a transaction stages, commits, rolls back and resets, only the head clears, compacts and drops collections, only a snapshot saves, and nothing writes through a snapshot.
- __Ragged inputs cross as they lie.__
  A slice of entries lends its keys as a strided run and its values through an accessor over the same records, and owned values cross as a tape of 32-bit or 64-bit offsets, so nothing is staged on the way in.
- __Arenas are lent and reused, never shared or hidden.__
  Executors make them through `ustore_arena_init`, and every verb whose outputs scale with the call borrows one as `&mut Arena`, blocking or deferred, while its result borrows it in turn, so the borrow checker retires stale views at compile time.
  No handle keeps an arena of its own.
- __Shorthand makes one-off arenas.__
  A `Collection` call with no arena to pass, such as `get` or `contains`, makes an arena for that call, copies its result out, and frees it: slower than reuse, and stateless.
- __A `DeferredOn` refuses borrowed inputs at compile time.__
  The library reads a deferred call's inputs after the verb returns, so the `Accepts` bound admits only owned ones, and passing `&[Key]` fails with "a deferred view needs owned inputs".
  The arena stays a borrow, which is safe because `ustore_arena_free` waits for the calls writing into it.
- __Deferred calls use the language's own idioms.__
  `status` polls through `ustore_outcome_status`, `wait` blocks through `ustore_outcome_wait`, and a `Deferred` is `IntoFuture`, so `.await` polls the status, asking to be polled again while the call is not final, since the library has no wake-up.
- __No life of its own.__
  The crate starts no threads and keeps no counts or queues, and needs no async runtime; releasing a `Deferred` rides `Drop`, which waits for the call first.
- __Nothing costs anything until it is used.__
  A blocking call allocates no box, a deferred one allocates one, and an arena allocates only when a call writes into it.
- __Statuses and modes are enums.__
  `Status`, `Watch`, `Durability`, `DropMode`, `Mood`, `Isolation`, `Transport`, `Engine`, `Modality`, `Role` and `Modification` mirror the C enumerators value for value, and spell themselves through the C name tables, so nothing is compared as a string.
- __Handlers cancel, and their panics resurface.__
  A progress handler is a closure lent for one call, and a panic inside it cancels the call rather than unwinding through C, then resurfaces once the call is final.
- __Borrowed pools are `unsafe`.__
  `Executor::on_pool` takes a raw `fu_pool_t`, which must outlive the executor, and safe Rust has no way to check that, so it is the one `unsafe` constructor.

Every verb of a view defers, each on owned inputs, and borrows its arena as a blocking verb does:

- __Values:__ `write` on keys beside a `BytesTape`, `remove` on keys, and `read`, `scan`, `sample` and `measure`.
- __Documents:__ `docs_write` on keys beside a `CharsTape` of JSON, on a `KeyedBy` of a tape, or on keys and a `CharsTape` of paths beside a `CharsTape` of values, `docs_read` on keys or on keys beside a `CharsTape` of paths, `docs_gather` on a `Vec<Column<'static>>`, and `docs_gist` on keys.
- __Graphs:__ `graph_write_edges` and `graph_remove_edges` on edges, `graph_write_vertices` and `graph_remove_vertices` on keys, and `graph_read_edges` and `graph_degrees`.
- __Collections:__ `collection_find` on a `String`, `collection_names` and `collection_list`, and `collection_drop` at the head.
- __Databases, transactions and snapshots:__ `clear` at the head, and `compact` there with a `'static` progress handler or none, `stage`, `commit`, `rollback` and `reset` of a transaction, and `save` of a snapshot on a `String`, with a progress handler as `compact` takes one.

`use ustore::PageEncoding;`

`use ustore::PagesImportConfig;`

`use ustore::PagesInsertConfig;`

`use ustore::PagesReadConfig;`

`use ustore::PagesScanConfig;`

`use ustore::pages::PagesImport;`

`use ustore::pages::PagesInsert;`

`use ustore::pages::PagesRemove;`

`use ustore::pages::PagesMove;`

`use ustore::pages::PagesSplice;`

`use ustore::pages::PagesSetAttributes;`

`use ustore::pages::PagesRemoveAttributes;`

`use ustore::pages::PagesRead;`

`use ustore::pages::PagesScan;`

## PageEncoding

The encoding pages render in, as `ustore_page_encoding_t` spells it.

```rust
pub enum PageEncoding
```

- `Html` = `0`: HTML, rendered back as markup.
- `Xml` = `1`: XML, with every element and attribute kept as written.
- `Markdown` = `2`: Markdown.
- `Text` = `3`: The text of every run in document order.
- `Json` = `4`: The element tree as JSON.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Default`, `Hash`, `Display`, `FromStr`, `From<[PageEncoding](#PageEncoding)>`

## PagesImportConfig

The markup imported pages arrive in and how the import reports; see [`On::pages_import`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_import).

```rust
pub struct PagesImportConfig<'config>
```

- `encoding` `PageEncoding`: The encoding of the markup.
- `progress` `Option<&'config mut ProgressCallback<'config>>`: Reports the pages imported and stops wherever it says to.

Implements: `From<[PageEncoding](#PageEncoding)>`

## PagesInsertConfig

Where inserted elements land and which keys they take; see [`On::pages_insert`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_insert).

```rust
pub struct PagesInsertConfig<'config>
```

- `elements` `&'config [Key]`: The key of the first element of every fragment; minted in every task when empty.
- `parents` `&'config [Key]`: The element every fragment lands under; the root in every task when empty.
- `anchors` `&'config [Key]`: The sibling every fragment lands after; the front in every task when empty.
- `encoding` `PageEncoding`: The encoding of the fragments.

Implements: `Clone`, `Copy`, `Debug`, `From<[PageEncoding](#PageEncoding)>`

## PagesReadConfig

What a page read returns and how; see [`On::pages_read`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_read).

```rust
pub struct PagesReadConfig<'config>
```

- `elements` `&'config [Key]`: Only these elements of each page; every element when empty.
- `outputs_encoding` `PageEncoding`: The markup the fragments come back in.

Implements: `Clone`, `Copy`, `Debug`, `From<[PageEncoding](#PageEncoding)>`

## PagesScanConfig

The page keys a scan keeps, what admits them and how it reports; see [`On::pages_scan`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_scan).

```rust
pub struct PagesScanConfig<'config>
```

- `wanted` `usize`: Page keys kept, at most.
- `matching` `Matching<'config>`: Admits only the pages its filter and predicate approve; every page by default.
- `mode` `ScanMode`: In what order the page keys come.
- `progress` `Option<&'config mut ProgressCallback<'config>>`: Reports the scans finished and stops wherever it says to.

Implements: `From<usize>`

## PagesImport

A replacement of whole pages; see [`On::pages_import`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_import).

```rust
pub struct PagesImport<'collections, 'config, Keys, Markups>
```

Implements: `Debug`

## PagesInsert

An insertion of parsed fragments; see [`On::pages_insert`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_insert).

```rust
pub struct PagesInsert<'arena, 'collections, 'config, Keys, Fragments>
```

Implements: `Debug`

## PagesRemove

A removal of elements with their subtrees; see [`On::pages_remove`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_remove).

```rust
pub struct PagesRemove<'collections, Keys, Elements>
```

Implements: `Debug`

## PagesMove

A move of elements with their subtrees; see [`On::pages_move`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_move).

```rust
pub struct PagesMove<'collections, Keys, Elements, Parents, Anchors>
```

Implements: `Debug`

## PagesSplice

A replacement of runs of text inside elements; see [`On::pages_splice`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_splice).

```rust
pub struct PagesSplice<'collections, Keys, Elements, Starts, Lengths, Texts>
```

Implements: `Debug`

## PagesSetAttributes

A setting of attributes of elements; see [`On::pages_set_attributes`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_set_attributes).

```rust
pub struct PagesSetAttributes<'collections, Keys, Elements, Fields, Texts>
```

Implements: `Debug`

## PagesRemoveAttributes

A removal of attributes of elements; see [`On::pages_remove_attributes`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_remove_attributes).

```rust
pub struct PagesRemoveAttributes<'collections, Keys, Elements, Fields>
```

Implements: `Debug`

## PagesRead

A rendering of pages or subtrees; see [`On::pages_read`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_read).

```rust
pub struct PagesRead<'arena, 'collections, 'config, Keys>
```

Implements: `Debug`

## PagesScan

A walk over the keys of one pages collection; see [`On::pages_scan`](https://www.unum.cloud/docs/ustore/rust/batches-and-arenas.md#pages_scan).

```rust
pub struct PagesScan<'arena, 'config>
```

Implements: `Debug`

