From fb6d0d55b5065531f8252b8fdeda4519ca176755 Mon Sep 17 00:00:00 2001 From: Jeffrey Rooks Date: Fri, 15 May 2026 20:36:38 -0400 Subject: [PATCH] add table accessor --- crates/codegen/src/rust.rs | 13 +++++++++++++ sdks/rust/src/lib.rs | 4 ++-- sdks/rust/src/table.rs | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/crates/codegen/src/rust.rs b/crates/codegen/src/rust.rs index 638d6f29ec8..03d58cd7530 100644 --- a/crates/codegen/src/rust.rs +++ b/crates/codegen/src/rust.rs @@ -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); @@ -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}`. +pub struct {table_accessor}; + +impl __sdk::TableAccessor 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}`. /// diff --git a/sdks/rust/src/lib.rs b/sdks/rust/src/lib.rs index d99447d440f..365b0e1cd33 100644 --- a/sdks/rust/src/lib.rs +++ b/sdks/rust/src/lib.rs @@ -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; @@ -62,7 +62,7 @@ pub mod __codegen { pub use crate::subscription::{OnEndedCallback, SubscriptionBuilder, SubscriptionHandleImpl}; pub use crate::{ ConnectionId, DbConnectionBuilder, DbContext, Event, EventTable, Identity, ReducerEvent, ScheduleAt, Table, - TableWithPrimaryKey, TimeDuration, Timestamp, Uuid, + TableAccessor, TableWithPrimaryKey, TimeDuration, Timestamp, Uuid, }; } diff --git a/sdks/rust/src/table.rs b/sdks/rust/src/table.rs index fe42c613a4a..bb5e5c2cf57 100644 --- a/sdks/rust/src/table.rs +++ b/sdks/rust/src/table.rs @@ -7,6 +7,23 @@ //! 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. +/// +/// This trait is implemented by generated marker types and preserves the +/// lifetime relationship between a database view and its table handles. +pub trait TableAccessor { + /// 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>; +} + /// Trait implemented by table handles, 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`.