Skip to content

Commit

Permalink
Start working on rust documentation update.
Browse files Browse the repository at this point in the history
More docs

One more patch

More table docs

More docs

Denser sats comments

Move comments

More doc rewriting

Substantial rewrite of main doc slug

More links and emphasis

Hmm

Document macros inline in the bindings crate to make links better

Fix some errors in rust module bindings docs + work on schedule documentation

Table macro docs polish

A day of writing

WIP editing

TODO on Identity APIs

Update BTreeIndex docs

Move lifecycle docs to root

Move reducer docs again, fix links

Minor crate root edits

Reducer commentary

Edits

Finish writing docs

Fix links

Typo

Remove dead docs

Typo

Fix outdated API

More small fixes

Add 'Automatic Migrations' section

Think incredibly hard....

Weird space

More formatting and spacing, use no_run instead of ignore

Less passive

Fix old names in docs

Fix doctests and some comments

Document documentation

A few more comments

Fix all links

More comments addressed

Kill dead
  • Loading branch information
kazimuth committed Feb 19, 2025
1 parent 32e24b4 commit 5a215fd
Show file tree
Hide file tree
Showing 30 changed files with 1,680 additions and 330 deletions.
179 changes: 7 additions & 172 deletions crates/bindings-macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
//! Defines procedural macros like `#[spacetimedb::table]`,
//! simplifying writing SpacetimeDB modules in Rust.
// DO NOT WRITE (public) DOCS IN THIS MODULE.
// Docs should be written in the `spacetimedb` crate (i.e. `bindings/`) at reexport sites
// using `#[doc(inline)]`.
// We do this so that links to library traits, structs, etc can resolve correctly.
//
// (private documentation for the macro authors is totally fine here and you SHOULD write that!)

mod reducer;
mod sats;
mod table;
Expand Down Expand Up @@ -96,76 +103,6 @@ mod sym {
}
}

/// Marks a function as a spacetimedb reducer.
///
/// A reducer is a function which traverses and updates the database,
/// a sort of stored procedure that lives in the database, and which can be invoked remotely.
/// Each reducer call runs in its own transaction,
/// and its updates to the database are only committed if the reducer returns successfully.
///
/// A reducer may take no arguments, like so:
///
/// ```rust,ignore
/// #[spacetimedb::reducer]
/// pub fn hello_world() {
/// println!("Hello, World!");
/// }
/// ```
///
/// But it may also take some:
/// ```rust,ignore
/// #[spacetimedb::reducer]
/// pub fn add_person(name: String, age: u16) {
/// // Logic to add a person with `name` and `age`.
/// }
/// ```
///
/// Reducers cannot return values, but can return errors.
/// To do so, a reducer must have a return type of `Result<(), impl Debug>`.
/// When such an error occurs, it will be formatted and printed out to logs,
/// resulting in an aborted transaction.
///
/// # Lifecycle Reducers
///
/// You can specify special lifecycle reducers that are run at set points in
/// the module's lifecycle. You can have one each per module.
///
/// ## `#[spacetimedb::reducer(init)]`
///
/// This reducer is run the first time a module is published
/// and anytime the database is cleared.
///
/// The reducer cannot be called manually
/// and may not have any parameters except for `ReducerContext`.
/// If an error occurs when initializing, the module will not be published.
///
/// ## `#[spacetimedb::reducer(client_connected)]`
///
/// This reducer is run when a client connects to the SpacetimeDB module.
/// Their identity can be found in the sender value of the `ReducerContext`.
///
/// The reducer cannot be called manually
/// and may not have any parameters except for `ReducerContext`.
/// If an error occurs in the reducer, the client will be disconnected.
///
///
/// ## `#[spacetimedb::reducer(client_disconnected)]`
///
/// This reducer is run when a client disconnects from the SpacetimeDB module.
/// Their identity can be found in the sender value of the `ReducerContext`.
///
/// The reducer cannot be called manually
/// and may not have any parameters except for `ReducerContext`.
/// If an error occurs in the disconnect reducer,
/// the client is still recorded as disconnected.
///
/// ## `#[spacetimedb::reducer(update)]`
///
/// This reducer is run when the module is updated,
/// i.e., when publishing a module for a database that has already been initialized.
///
/// The reducer cannot be called manually and may not have any parameters.
/// If an error occurs when initializing, the module will not be published.
#[proc_macro_attribute]
pub fn reducer(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
cvt_attr::<ItemFn>(args, item, quote!(), |args, original_function| {
Expand All @@ -190,77 +127,6 @@ fn derive_table_helper_attr() -> Attribute {
.unwrap()
}

/// Generates code for treating this struct type as a table.
///
/// Among other things, this derives `Serialize`, `Deserialize`,
/// `SpacetimeType`, and `Table` for our type.
///
/// # Example
///
/// ```ignore
/// #[spacetimedb::table(name = users, public)]
/// pub struct User {
/// #[auto_inc]
/// #[primary_key]
/// pub id: u32,
/// #[unique]
/// pub username: String,
/// #[index(btree)]
/// pub popularity: u32,
/// }
/// ```
///
/// # Macro arguments
///
/// * `public` and `private`
///
/// Tables are private by default. If you'd like to make your table publically
/// accessible by anyone, put `public` in the macro arguments (e.g.
/// `#[spacetimedb::table(public)]`). You can also specify `private` if
/// you'd like to be specific. This is fully separate from Rust's module visibility
/// system; `pub struct` or `pub(crate) struct` do not affect the table visibility, only
/// the visibility of the items in your own source code.
///
/// * `index(name = my_index, btree(columns = [a, b, c]))`
///
/// You can specify an index on 1 or more of the table's columns with the above syntax.
/// You can also just put `#[index(btree)]` on the field itself if you only need
/// a single-column attribute; see column attributes below.
///
/// * `name = my_table`
///
/// Specify the name of the table in the database, if you want it to be different from
/// the name of the struct.
///
/// # Column (field) attributes
///
/// * `#[auto_inc]`
///
/// Creates a database sequence.
///
/// When a row is inserted with the annotated field set to `0` (zero),
/// the sequence is incremented, and this value is used instead.
/// Can only be used on numeric types and may be combined with indexes.
///
/// Note that using `#[auto_inc]` on a field does not also imply `#[primary_key]` or `#[unique]`.
/// If those semantics are desired, those attributes should also be used.
///
/// * `#[unique]`
///
/// Creates an index and unique constraint for the annotated field.
///
/// * `#[primary_key]`
///
/// Similar to `#[unique]`, but generates additional CRUD methods.
///
/// * `#[index(btree)]`
///
/// Creates a single-column index with the specified algorithm.
///
/// [`Serialize`]: https://docs.rs/spacetimedb/latest/spacetimedb/trait.Serialize.html
/// [`Deserialize`]: https://docs.rs/spacetimedb/latest/spacetimedb/trait.Deserialize.html
/// [`SpacetimeType`]: https://docs.rs/spacetimedb/latest/spacetimedb/trait.SpacetimeType.html
/// [`TableType`]: https://docs.rs/spacetimedb/latest/spacetimedb/trait.TableType.html
#[proc_macro_attribute]
pub fn table(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
// put this on the struct so we don't get unknown attribute errors
Expand Down Expand Up @@ -376,37 +242,6 @@ pub fn schema_type(input: StdTokenStream) -> StdTokenStream {
})
}

/// Generates code for registering a row-level security rule.
///
/// This attribute must be applied to a `const` binding of type [`Filter`].
/// It will be interpreted as a filter on the table to which it applies, for all client queries.
/// If a module contains multiple `client_visibility_filter`s for the same table,
/// they will be unioned together as if by SQL `OR`,
/// so that any row permitted by at least one filter is visible.
///
/// The `const` binding's identifier must be unique within the module.
///
/// The query follows the same syntax as a subscription query.
///
/// ## Example:
///
/// ```rust,ignore
/// /// Players can only see what's in their chunk
/// #[spacetimedb::client_visibility_filter]
/// const PLAYERS_SEE_ENTITIES_IN_SAME_CHUNK: Filter = Filter::Sql("
/// SELECT * FROM LocationState WHERE chunk_index IN (
/// SELECT chunk_index FROM LocationState WHERE entity_id IN (
/// SELECT entity_id FROM UserState WHERE identity = @sender
/// )
/// )
/// ");
/// ```
///
/// Queries are not checked for syntactic or semantic validity
/// until they are processed by the SpacetimeDB host.
/// This means that errors in queries, such as syntax errors, type errors or unknown tables,
/// will be reported during `spacetime publish`, not at compile time.
#[doc(hidden)] // TODO: RLS filters are currently unimplemented, and are not enforced.
#[proc_macro_attribute]
pub fn client_visibility_filter(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
ok_or_compile_error(|| {
Expand Down
8 changes: 4 additions & 4 deletions crates/bindings-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ pub mod raw {
pub fn bytes_source_read(source: BytesSource, buffer_ptr: *mut u8, buffer_len_ptr: *mut usize) -> i16;

/// Logs at `level` a `message` message occuring in `filename:line_number`
/// with [`target`](target) being the module path at the `log!` invocation site.
/// with `target` being the module path at the `log!` invocation site.
///
/// These various pointers are interpreted lossily as UTF-8 strings with a corresponding `_len`.
///
Expand Down Expand Up @@ -592,7 +592,7 @@ pub mod raw {

/// What strategy does the database index use?
///
/// See also: https://www.postgresql.org/docs/current/sql-createindex.html
/// See also: <https://www.postgresql.org/docs/current/sql-createindex.html>
#[repr(u8)]
#[non_exhaustive]
pub enum IndexType {
Expand Down Expand Up @@ -885,7 +885,7 @@ pub fn datastore_delete_all_by_eq_bsatn(table_id: TableId, relation: &[u8]) -> R

/// Starts iteration on each row, as BSATN-encoded, of a table identified by `table_id`.
/// Returns iterator handle is written to the `out` pointer.
/// This handle can be advanced by [`row_iter_bsatn_advance`].
/// This handle can be advanced by [`RowIter::read`].
///
/// # Errors
///
Expand Down Expand Up @@ -920,7 +920,7 @@ pub fn datastore_table_scan_bsatn(table_id: TableId) -> Result<RowIter, Errno> {
/// which is unique for the module.
///
/// On success, the iterator handle is written to the `out` pointer.
/// This handle can be advanced by [`row_iter_bsatn_advance`].
/// This handle can be advanced by [`RowIter::read`].
///
/// # Non-obvious queries
///
Expand Down
Loading

0 comments on commit 5a215fd

Please sign in to comment.