Skip to content

Commit 80e950e

Browse files
committed
explicit names macro
1 parent 3f93250 commit 80e950e

10 files changed

Lines changed: 213 additions & 11 deletions

File tree

crates/bindings-macro/src/procedure.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::reducer::{assert_only_lifetime_generics, extract_typed_args};
1+
use crate::reducer::{assert_only_lifetime_generics, extract_typed_args, generate_explicit_names_impl};
22
use crate::sym;
33
use crate::util::{check_duplicate, ident_to_litstr, match_meta};
44
use proc_macro2::TokenStream;
@@ -32,6 +32,7 @@ impl ProcedureArgs {
3232
pub(crate) fn procedure_impl(_args: ProcedureArgs, original_function: &ItemFn) -> syn::Result<TokenStream> {
3333
let func_name = &original_function.sig.ident;
3434
let vis = &original_function.vis;
35+
let explicit_name = _args.name.as_ref();
3536

3637
let procedure_name = ident_to_litstr(func_name);
3738

@@ -86,6 +87,8 @@ pub(crate) fn procedure_impl(_args: ProcedureArgs, original_function: &ItemFn) -
8687
}
8788
};
8889

90+
let generate_explicit_names = generate_explicit_names_impl(&procedure_name.value(), func_name, explicit_name);
91+
8992
Ok(quote! {
9093
const _: () = {
9194
#generated_describe_function

crates/bindings-macro/src/reducer.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ pub(crate) fn reducer_impl(args: ReducerArgs, original_function: &ItemFn) -> syn
104104

105105
let typed_args = extract_typed_args(original_function)?;
106106

107+
let explicit_name = args.name.as_ref();
108+
109+
let generate_explicit_names = generate_explicit_names_impl(&reducer_name.value(), func_name, explicit_name);
110+
107111
// Extract all function parameter names.
108112
let opt_arg_names = typed_args.iter().map(|arg| {
109113
if let syn::Pat::Ident(i) = &*arg.pat {
@@ -165,5 +169,36 @@ pub(crate) fn reducer_impl(args: ReducerArgs, original_function: &ItemFn) -> syn
165169
const ARG_NAMES: &'static [Option<&'static str>] = &[#(#opt_arg_names),*];
166170
const INVOKE: Self::Invoke = #func_name::invoke;
167171
}
172+
173+
#generate_explicit_names
168174
})
169175
}
176+
177+
pub(crate) fn generate_explicit_names_impl(
178+
func_name: &str,
179+
func_handle: &Ident,
180+
explicit_name: Option<&LitStr>,
181+
) -> TokenStream {
182+
let mut explicit_names_body = Vec::new();
183+
184+
// Table name
185+
if let Some(explicit_name) = explicit_name {
186+
explicit_names_body.push(quote! {
187+
names.insert_function(
188+
#func_name,
189+
#explicit_name,
190+
);
191+
});
192+
};
193+
194+
quote! {
195+
196+
impl spacetimedb::rt::ExplicitNames for #func_handle {
197+
fn explicit_names() -> spacetimedb::spacetimedb_lib::ExplicitNames {
198+
let mut names = spacetimedb::spacetimedb_lib::ExplicitNames::default();
199+
#(#explicit_names_body)*
200+
names
201+
}
202+
}
203+
}
204+
}

crates/bindings-macro/src/table.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use syn::{parse_quote, Ident, Path, Token};
1717

1818
pub(crate) struct TableArgs {
1919
access: Option<TableAccess>,
20-
_name: Option<LitStr>,
20+
name: Option<LitStr>,
2121
scheduled: Option<ScheduledArg>,
2222
accessor: Ident,
2323
indices: Vec<IndexArg>,
@@ -96,7 +96,7 @@ impl TableArgs {
9696
accessor = Some(value.parse()?);
9797
}
9898
sym::name => {
99-
check_duplicate(&accessor, &meta)?;
99+
check_duplicate(&name, &meta)?;
100100
let value = meta.value()?;
101101
name = Some(value.parse()?);
102102
}
@@ -121,7 +121,7 @@ impl TableArgs {
121121
scheduled,
122122
accessor,
123123
indices,
124-
_name: name,
124+
name,
125125
})
126126
}
127127
}
@@ -714,6 +714,7 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
714714

715715
let original_struct_ident = sats_ty.ident;
716716
let table_ident = &args.accessor;
717+
let explicit_table_name = args.name.as_ref().map(|s| s.value());
717718
let view_trait_ident = format_ident!("{}__view", table_ident);
718719
let query_trait_ident = format_ident!("{}__query", table_ident);
719720
let query_cols_struct = format_ident!("{}Cols", original_struct_ident);
@@ -1019,6 +1020,8 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
10191020
}
10201021
};
10211022

1023+
let explicit_names_impl = generate_explicit_names_impl(&table_name, &tablehandle_ident, &explicit_table_name);
1024+
10221025
let register_describer_symbol = format!("__preinit__20_register_describer_{table_ident}");
10231026

10241027
let describe_table_func = quote! {
@@ -1178,6 +1181,8 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
11781181

11791182
#tabletype_impl
11801183

1184+
#explicit_names_impl
1185+
11811186
#[allow(non_camel_case_types)]
11821187
mod __indices {
11831188
#[allow(unused)]
@@ -1198,3 +1203,32 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
11981203

11991204
Ok(emission)
12001205
}
1206+
1207+
fn generate_explicit_names_impl(
1208+
table_name: &str,
1209+
tablehandle_ident: &Ident,
1210+
explicit_table_name: &Option<String>,
1211+
) -> TokenStream {
1212+
let mut explicit_names_body = Vec::new();
1213+
1214+
// Table name
1215+
if let Some(explicit_table_name) = explicit_table_name {
1216+
explicit_names_body.push(quote! {
1217+
names.insert_table(
1218+
#table_name,
1219+
#explicit_table_name,
1220+
);
1221+
});
1222+
};
1223+
1224+
quote! {
1225+
1226+
impl spacetimedb::rt::ExplicitNames for #tablehandle_ident {
1227+
fn explicit_names() -> spacetimedb::spacetimedb_lib::ExplicitNames {
1228+
let mut names = spacetimedb::spacetimedb_lib::ExplicitNames::default();
1229+
#(#explicit_names_body)*
1230+
names
1231+
}
1232+
}
1233+
}
1234+
}

crates/bindings-macro/src/view.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ use syn::ext::IdentExt;
55
use syn::parse::Parser;
66
use syn::{FnArg, ItemFn, LitStr};
77

8+
use crate::reducer::generate_explicit_names_impl;
89
use crate::sym;
910
use crate::util::{check_duplicate_msg, match_meta};
1011

1112
pub(crate) struct ViewArgs {
12-
_name: Option<LitStr>,
13+
name: Option<LitStr>,
1314
accessor: Ident,
1415
#[allow(unused)]
1516
public: bool,
@@ -49,7 +50,7 @@ impl ViewArgs {
4950
let () = public
5051
.ok_or_else(|| syn::Error::new(Span::call_site(), "views must be `public`, e.g. `#[view(public)]`"))?;
5152
Ok(Self {
52-
_name: name,
53+
name,
5354
public: true,
5455
accessor,
5556
})
@@ -147,6 +148,10 @@ pub(crate) fn view_impl(args: ViewArgs, original_function: &ItemFn) -> syn::Resu
147148
}
148149
};
149150

151+
let explicit_name = args.name.as_ref();
152+
153+
let generate_explicit_names = generate_explicit_names_impl(&view_name, func_name, explicit_name);
154+
150155
Ok(quote! {
151156
const _: () = { #generated_describe_function };
152157

@@ -196,5 +201,7 @@ pub(crate) fn view_impl(args: ViewArgs, original_function: &ItemFn) -> syn::Resu
196201
Some(<#ret_ty as spacetimedb::SpacetimeType>::make_type(ts))
197202
}
198203
}
204+
205+
#generate_explicit_names
199206
})
200207
}

crates/bindings/src/rt.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::query_builder::Query;
44
use crate::table::IndexAlgo;
55
use crate::{sys, AnonymousViewContext, IterBuf, ReducerContext, ReducerResult, SpacetimeType, Table, ViewContext};
66
use spacetimedb_lib::bsatn::EncodeError;
7-
use spacetimedb_lib::db::raw_def::v10::RawModuleDefV10Builder;
7+
use spacetimedb_lib::db::raw_def::v10::{ExplicitNameEntry, ExplicitNames as RawExplicitNames, RawModuleDefV10Builder};
88
pub use spacetimedb_lib::db::raw_def::v9::Lifecycle as LifecycleReducer;
99
use spacetimedb_lib::db::raw_def::v9::{RawIndexAlgorithm, TableType, ViewResultHeader};
1010
use spacetimedb_lib::de::{self, Deserialize, DeserializeOwned, Error as _, SeqProductAccess};
@@ -141,7 +141,7 @@ pub trait AnonymousView<'de, A: Args<'de>, T: ViewReturn> {
141141
}
142142

143143
/// A trait for types that can *describe* a callable function such as a reducer or view.
144-
pub trait FnInfo {
144+
pub trait FnInfo: ExplicitNames {
145145
/// The type of function to invoke.
146146
type Invoke;
147147

@@ -735,6 +735,8 @@ pub fn register_table<T: Table>() {
735735
}
736736

737737
table.finish();
738+
739+
module.inner.add_explicit_names(T::explicit_names());
738740
})
739741
}
740742

@@ -762,6 +764,8 @@ pub fn register_reducer<'a, A: Args<'a>, I: FnInfo<Invoke = ReducerFn>>(_: impl
762764
module.inner.add_reducer(I::NAME, params);
763765
}
764766
module.reducers.push(I::INVOKE);
767+
768+
module.inner.add_explicit_names(I::explicit_names());
765769
})
766770
}
767771

@@ -777,6 +781,8 @@ where
777781
let ret_ty = <Ret as SpacetimeType>::make_type(&mut module.inner);
778782
module.inner.add_procedure(I::NAME, params, ret_ty);
779783
module.procedures.push(I::INVOKE);
784+
785+
module.inner.add_explicit_names(I::explicit_names());
780786
})
781787
}
782788

@@ -794,6 +800,8 @@ where
794800
.inner
795801
.add_view(I::NAME, module.views.len(), true, false, params, return_type);
796802
module.views.push(I::INVOKE);
803+
804+
module.inner.add_explicit_names(I::explicit_names());
797805
})
798806
}
799807

@@ -811,6 +819,8 @@ where
811819
.inner
812820
.add_view(I::NAME, module.views_anon.len(), true, true, params, return_type);
813821
module.views_anon.push(I::INVOKE);
822+
823+
module.inner.add_explicit_names(I::explicit_names());
814824
})
815825
}
816826

@@ -1273,3 +1283,9 @@ pub(crate) fn read_bytes_source_as<T: DeserializeOwned + 'static>(source: BytesS
12731283
bsatn::from_slice::<T>(&buf)
12741284
.unwrap_or_else(|err| panic!("Failed to BSATN-deserialize `{}`: {err:#?}", std::any::type_name::<T>()))
12751285
}
1286+
1287+
pub trait ExplicitNames {
1288+
fn explicit_names() -> RawExplicitNames {
1289+
RawExplicitNames::default()
1290+
}
1291+
}

crates/bindings/src/table.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{bsatn, sys, DeserializeOwned, IterBuf, Serialize, SpacetimeType, TableId};
1+
use crate::{bsatn, rt::ExplicitNames, sys, DeserializeOwned, IterBuf, Serialize, SpacetimeType, TableId};
22
use core::borrow::Borrow;
33
use core::convert::Infallible;
44
use core::fmt;
@@ -17,7 +17,7 @@ pub use spacetimedb_primitives::{ColId, IndexId};
1717
///
1818
/// To get a `TableHandle`
1919
// TODO: should we rename this `TableHandle`? Documenting this, I think that's much clearer.
20-
pub trait Table: TableInternal {
20+
pub trait Table: TableInternal + ExplicitNames {
2121
/// The type of rows stored in this table.
2222
type Row: SpacetimeType + Serialize + DeserializeOwned + Sized + 'static;
2323

crates/lib/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ enum-map = { workspace = true, optional = true }
5353
# For the 'proptest' feature.
5454
proptest = { workspace = true, optional = true }
5555
proptest-derive = { workspace = true, optional = true }
56+
spacetimedb-data-structures.workspace = true
5657

5758
[dev-dependencies]
5859
spacetimedb-sats = { path = "../sats", features = ["test"] }

0 commit comments

Comments
 (0)