Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions crates/codegen/src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ impl __sdk::InModule for {type_name} {{
let table_name = table.name.deref();
let table_name_pascalcase = table.accessor_name.deref().to_case(Case::Pascal);
let table_handle = table_name_pascalcase.clone() + "TableHandle";
let table_accessor = table_name_pascalcase.clone() + "TableAccessor";
let insert_callback_id = table_name_pascalcase.clone() + "InsertCallbackId";
let delete_callback_id = table_name_pascalcase.clone() + "DeleteCallbackId";
let accessor_trait = table_access_trait_name(&table.accessor_name);
Expand All @@ -148,6 +149,18 @@ pub struct {table_handle}<'ctx> {{
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}}

/// Lifetime-aware accessor marker for the table `{table_name}`.
Comment thread
onx2 marked this conversation as resolved.
pub struct {table_accessor};

impl __sdk::TableAccessor<super::RemoteTables> for {table_accessor} {{
type Row = {row_type};
type Handle<'db> = {table_handle}<'db>;

fn get<'db>(db: &'db super::RemoteTables) -> Self::Handle<'db> {{
db.{accessor_method}()
}}
}}

#[allow(non_camel_case_types)]
/// Extension trait for access to the table `{table_name}`.
///
Expand Down
72 changes: 72 additions & 0 deletions crates/codegen/tests/snapshots/codegen__codegen_rust.snap
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,18 @@ pub struct LoggedOutPlayerTableHandle<'ctx> {
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}

/// Lifetime-aware accessor marker for the table `logged_out_player`.
pub struct LoggedOutPlayerTableAccessor;

impl __sdk::TableAccessor<super::RemoteTables> for LoggedOutPlayerTableAccessor {
type Row = Player;
type Handle<'db> = LoggedOutPlayerTableHandle<'db>;

fn get<'db>(db: &'db super::RemoteTables) -> Self::Handle<'db> {
db.logged_out_player()
}
}

#[allow(non_camel_case_types)]
/// Extension trait for access to the table `logged_out_player`.
///
Expand Down Expand Up @@ -2091,6 +2103,18 @@ pub struct MyPlayerTableHandle<'ctx> {
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}

/// Lifetime-aware accessor marker for the table `my_player`.
pub struct MyPlayerTableAccessor;

impl __sdk::TableAccessor<super::RemoteTables> for MyPlayerTableAccessor {
type Row = Player;
type Handle<'db> = MyPlayerTableHandle<'db>;

fn get<'db>(db: &'db super::RemoteTables) -> Self::Handle<'db> {
db.my_player()
}
}

#[allow(non_camel_case_types)]
/// Extension trait for access to the table `my_player`.
///
Expand Down Expand Up @@ -2374,6 +2398,18 @@ pub struct PersonTableHandle<'ctx> {
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}

/// Lifetime-aware accessor marker for the table `person`.
pub struct PersonTableAccessor;

impl __sdk::TableAccessor<super::RemoteTables> for PersonTableAccessor {
type Row = Person;
type Handle<'db> = PersonTableHandle<'db>;

fn get<'db>(db: &'db super::RemoteTables) -> Self::Handle<'db> {
db.person()
}
}

#[allow(non_camel_case_types)]
/// Extension trait for access to the table `person`.
///
Expand Down Expand Up @@ -2729,6 +2765,18 @@ pub struct PlayerTableHandle<'ctx> {
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}

/// Lifetime-aware accessor marker for the table `player`.
pub struct PlayerTableAccessor;

impl __sdk::TableAccessor<super::RemoteTables> for PlayerTableAccessor {
type Row = Player;
type Handle<'db> = PlayerTableHandle<'db>;

fn get<'db>(db: &'db super::RemoteTables) -> Self::Handle<'db> {
db.player()
}
}

#[allow(non_camel_case_types)]
/// Extension trait for access to the table `player`.
///
Expand Down Expand Up @@ -3752,6 +3800,18 @@ pub struct TestDTableHandle<'ctx> {
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}

/// Lifetime-aware accessor marker for the table `test_d`.
pub struct TestDTableAccessor;

impl __sdk::TableAccessor<super::RemoteTables> for TestDTableAccessor {
type Row = TestD;
type Handle<'db> = TestDTableHandle<'db>;

fn get<'db>(db: &'db super::RemoteTables) -> Self::Handle<'db> {
db.test_d()
}
}

#[allow(non_camel_case_types)]
/// Extension trait for access to the table `test_d`.
///
Expand Down Expand Up @@ -4039,6 +4099,18 @@ pub struct TestFTableHandle<'ctx> {
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}

/// Lifetime-aware accessor marker for the table `test_f`.
pub struct TestFTableAccessor;

impl __sdk::TableAccessor<super::RemoteTables> for TestFTableAccessor {
type Row = TestFoobar;
type Handle<'db> = TestFTableHandle<'db>;

fn get<'db>(db: &'db super::RemoteTables) -> Self::Handle<'db> {
db.test_f()
}
}

#[allow(non_camel_case_types)]
/// Extension trait for access to the table `test_f`.
///
Expand Down
4 changes: 2 additions & 2 deletions sdks/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub use db_connection::DbConnectionBuilder;
pub use db_context::DbContext;
pub use error::{Error, Result};
pub use event::{Event, ReducerEvent, Status};
pub use table::{EventTable, Table, TableWithPrimaryKey};
pub use table::{EventTable, Table, TableAccessor, TableWithPrimaryKey};

pub use spacetime_module::SubscriptionHandle;
pub use spacetimedb_client_api_messages::websocket::v1::Compression;
Expand Down Expand Up @@ -63,7 +63,7 @@ pub mod __codegen {
pub use crate::table::{TableLike, WithDelete, WithInsert, WithUpdate};
pub use crate::{
ConnectionId, DbConnectionBuilder, DbContext, Event, EventTable, Identity, ReducerEvent, ScheduleAt, Table,
TableWithPrimaryKey, TimeDuration, Timestamp, Uuid,
TableAccessor, TableWithPrimaryKey, TimeDuration, Timestamp, Uuid,
};
}

Expand Down
27 changes: 27 additions & 0 deletions sdks/rust/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,33 @@
//! which mediate access to tables in the client cache.
//! Obtain a table handle by calling a method on `ctx.db`, where `ctx` is a `DbConnection` or `EventContext`.

/// Accesses a generated table handle from a database view.
///
/// For each table, this trait is implemented by a marker type generated by `spacetime generate`,
/// named in the form `{TableNamePascalCase}TableAccessor`.
/// These markers are primarily used when writing extensions to the SpacetimeDB client SDK,
/// and are not generally expected to be useful to applications building with the SpacetimeDB client SDK directly.
/// They were added for use by [the `bevy_stdb` project](https://github.com/onx2/bevy_stdb)
/// to simplify their interface for registering tables.
///
/// An instance of the marker type which implements this trait does not directly provide access to the client cache;
/// [`TableAccessor::get`] still requires a `DbView` derived from a `DbConnection` or context.
/// The table accessor exists only to simplify type inference in generic contexts.
/// Particularly, table accessor markers do not allow side-stepping the lifetime bounds on client cache access,
/// so it is not possible to use an accessor marker to view an inconsistent client cache state through an out-of-date event context.
pub trait TableAccessor<DbView: ?Sized> {
Comment thread
onx2 marked this conversation as resolved.
/// The type of rows stored in this table.
type Row: 'static;

/// The generated table handle type for a database view borrow.
type Handle<'db>
where
DbView: 'db;

/// Returns the generated table handle for `db`.
fn get<'db>(db: &'db DbView) -> Self::Handle<'db>;
}

/// Supports common table handle operations.
///
/// This trait is implemented by generated handles for persistent tables,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading