Skip to content
Open
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
2 changes: 1 addition & 1 deletion .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
max_width = 120
edition = "2021"
style_edition = "2021"
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ debug = true

[workspace.package]
version = "2.0.0"
edition = "2021"
edition = "2024"
# update rust-toolchain.toml too!
rust-version = "1.93.0"

Expand Down
8 changes: 4 additions & 4 deletions crates/auth/src/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,12 @@ impl TryInto<SpacetimeIdentityClaims> for IncomingClaims {

let computed_identity = Identity::from_claims(&self.issuer, &self.subject);
// If an identity is provided, it must match the computed identity.
if let Some(token_identity) = self.identity {
if token_identity != computed_identity {
return Err(anyhow::anyhow!(
if let Some(token_identity) = self.identity
&& token_identity != computed_identity
{
return Err(anyhow::anyhow!(
"Identity mismatch: token identity {token_identity:?} does not match computed identity {computed_identity:?}",
));
}
}

Ok(SpacetimeIdentityClaims {
Expand Down
36 changes: 18 additions & 18 deletions crates/bench/src/schemas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ pub fn table_name<T: BenchTable>(style: IndexStrategy) -> TableName {
#[derive(Clone)]
pub struct XorShiftLite(pub u64);
impl XorShiftLite {
fn gen(&mut self) -> u64 {
fn r#gen(&mut self) -> u64 {
let old = self.0;
self.0 ^= self.0 << 13;
self.0 ^= self.0 >> 7;
Expand All @@ -189,36 +189,36 @@ pub trait RandomTable {
/// Then in the filter benchmarks, `mean_result_count = table_size / buckets`.
///
/// Currently the same number of buckets is used for all attributes.
fn gen(id: u32, rng: &mut XorShiftLite, buckets: u64) -> Self;
fn r#gen(id: u32, rng: &mut XorShiftLite, buckets: u64) -> Self;
}

impl RandomTable for u32_u64_str {
fn gen(id: u32, rng: &mut XorShiftLite, buckets: u64) -> Self {
let name = nth_name(rng.gen() % buckets).into();
let age = rng.gen() % buckets;
fn r#gen(id: u32, rng: &mut XorShiftLite, buckets: u64) -> Self {
let name = nth_name(rng.r#gen() % buckets).into();
let age = rng.r#gen() % buckets;
u32_u64_str { id, name, age }
}
}

impl RandomTable for u32_u64_u64 {
fn gen(id: u32, rng: &mut XorShiftLite, buckets: u64) -> Self {
let x = rng.gen() % buckets;
let y = rng.gen() % buckets;
fn r#gen(id: u32, rng: &mut XorShiftLite, buckets: u64) -> Self {
let x = rng.r#gen() % buckets;
let y = rng.r#gen() % buckets;
u32_u64_u64 { id, x, y }
}
}

impl RandomTable for u64_u64_u32 {
fn gen(id: u32, rng: &mut XorShiftLite, buckets: u64) -> Self {
let x = rng.gen() % buckets;
let y = rng.gen() % buckets;
fn r#gen(id: u32, rng: &mut XorShiftLite, buckets: u64) -> Self {
let x = rng.r#gen() % buckets;
let y = rng.r#gen() % buckets;
u64_u64_u32 { x, y, id }
}
}

pub fn create_sequential<T: RandomTable>(seed: u64, count: u32, buckets: u64) -> Vec<T> {
let mut rng = XorShiftLite(seed);
(0..count).map(|id| T::gen(id, &mut rng, buckets)).collect()
(0..count).map(|id| T::r#gen(id, &mut rng, buckets)).collect()
}

/// Create a table whose first `identical` rows are identical except for their `id` column.
Expand All @@ -237,13 +237,13 @@ pub fn create_partly_identical<T: RandomTable>(seed: u64, identical: u64, total:
for _ in 0..identical {
// clone to preserve rng state
let mut rng_ = rng.clone();
result.push(T::gen(id as u32, &mut rng_, buckets));
result.push(T::r#gen(id as u32, &mut rng_, buckets));
id += 1;
}
// advance rng
drop(T::gen(id as u32, &mut rng, buckets));
drop(T::r#gen(id as u32, &mut rng, buckets));
for _ in identical..total {
result.push(T::gen(id as u32, &mut rng, buckets));
result.push(T::r#gen(id as u32, &mut rng, buckets));
id += 1;
}
result
Expand All @@ -254,8 +254,8 @@ pub fn create_random<T: RandomTable>(seed: u64, count: u32, buckets: u64) -> Vec
let mut rng = XorShiftLite(seed);
(0..count)
.map(|_| {
let id = (rng.gen() % (u32::MAX as u64)) as u32;
T::gen(id, &mut rng, buckets)
let id = (rng.r#gen() % (u32::MAX as u64)) as u32;
T::r#gen(id, &mut rng, buckets)
})
.collect()
}
Expand Down Expand Up @@ -362,7 +362,7 @@ mod tests {
}
// sample some earlier names to make sure we haven't overlapped
for _ in 0..30 {
let prev = rng.gen() % n;
let prev = rng.r#gen() % n;
assert!(
name != nth_name(prev),
"names should not repeat, but {}->{} and {}->{}",
Expand Down
8 changes: 4 additions & 4 deletions crates/bench/src/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,10 @@ fn memo_query<F: FnOnce() -> String>(bench_name: BenchName, table_id: &str, gene
// fast path
let queries = QUERIES.read().unwrap();

if let Some(bench_queries) = queries.get(&bench_name) {
if let Some(query) = bench_queries.get(table_id) {
return query.clone();
}
if let Some(bench_queries) = queries.get(&bench_name)
&& let Some(query) = bench_queries.get(table_id)
{
return query.clone();
}

// slow path
Expand Down
140 changes: 70 additions & 70 deletions crates/bindings-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,81 @@
// (private documentation for the macro authors is totally fine here and you SHOULD write that!)

mod procedure;

#[proc_macro_attribute]
pub fn procedure(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
cvt_attr::<ItemFn>(args, item, quote!(), |args, original_function| {
let args = procedure::ProcedureArgs::parse(args)?;
procedure::procedure_impl(args, original_function)
})
}
mod reducer;

#[proc_macro_attribute]
pub fn reducer(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
cvt_attr::<ItemFn>(args, item, quote!(), |args, original_function| {
let args = reducer::ReducerArgs::parse(args)?;
reducer::reducer_impl(args, original_function)
})
}
mod sats;
mod table;

#[proc_macro_attribute]
pub fn table(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
// put this on the struct so we don't get unknown attribute errors
let derive_table_helper: syn::Attribute = derive_table_helper_attr();

ok_or_compile_error(|| {
let item = TokenStream::from(item);
let mut derive_input: syn::DeriveInput = syn::parse2(item.clone())?;

// Add `derive(__TableHelper)` only if it's not already in the attributes of the `derive_input.`
// If multiple `#[table]` attributes are applied to the same `struct` item,
// this will ensure that we don't emit multiple conflicting implementations
// for traits like `SpacetimeType`, `Serialize` and `Deserialize`.
//
// We need to push at the end, rather than the beginning,
// because rustc expands attribute macros (including derives) top-to-bottom,
// and we need *all* `#[table]` attributes *before* the `derive(__TableHelper)`.
// This way, the first `table` will insert a `derive(__TableHelper)`,
// and all subsequent `#[table]`s on the same `struct` will see it,
// and not add another.
//
// Note, thank goodness, that `syn`'s `PartialEq` impls (provided with the `extra-traits` feature)
// skip any [`Span`]s contained in the items,
// thereby comparing for syntactic rather than structural equality. This shouldn't matter,
// since we expect that the `derive_table_helper` will always have the same [`Span`]s,
// but it's nice to know.
if !derive_input.attrs.contains(&derive_table_helper) {
derive_input.attrs.push(derive_table_helper);
}

let args = table::TableArgs::parse(args.into(), &derive_input.ident)?;
let generated = table::table_impl(args, &derive_input)?;
Ok(TokenStream::from_iter([quote!(#derive_input), generated]))
})
}
mod util;
mod view;

#[proc_macro_attribute]
pub fn view(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
let item_ts: TokenStream = item.into();
let original_function = match syn::parse2::<ItemFn>(item_ts.clone()) {
Ok(f) => f,
Err(e) => return TokenStream::from_iter([item_ts, e.into_compile_error()]).into(),
};
let args = match view::ViewArgs::parse(args.into(), &original_function.sig.ident) {
Ok(a) => a,
Err(e) => return TokenStream::from_iter([item_ts, e.into_compile_error()]).into(),
};
match view::view_impl(args, &original_function) {
Ok(ts) => ts.into(),
Err(e) => TokenStream::from_iter([item_ts, e.into_compile_error()]).into(),
}
}

use proc_macro::TokenStream as StdTokenStream;
use proc_macro2::TokenStream;
use quote::quote;
Expand Down Expand Up @@ -109,39 +178,6 @@ mod sym {
}
}

#[proc_macro_attribute]
pub fn procedure(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
cvt_attr::<ItemFn>(args, item, quote!(), |args, original_function| {
let args = procedure::ProcedureArgs::parse(args)?;
procedure::procedure_impl(args, original_function)
})
}

#[proc_macro_attribute]
pub fn reducer(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
cvt_attr::<ItemFn>(args, item, quote!(), |args, original_function| {
let args = reducer::ReducerArgs::parse(args)?;
reducer::reducer_impl(args, original_function)
})
}

#[proc_macro_attribute]
pub fn view(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
let item_ts: TokenStream = item.into();
let original_function = match syn::parse2::<ItemFn>(item_ts.clone()) {
Ok(f) => f,
Err(e) => return TokenStream::from_iter([item_ts, e.into_compile_error()]).into(),
};
let args = match view::ViewArgs::parse(args.into(), &original_function.sig.ident) {
Ok(a) => a,
Err(e) => return TokenStream::from_iter([item_ts, e.into_compile_error()]).into(),
};
match view::view_impl(args, &original_function) {
Ok(ts) => ts.into(),
Err(e) => TokenStream::from_iter([item_ts, e.into_compile_error()]).into(),
}
}

/// It turns out to be shockingly difficult to construct an [`Attribute`].
/// That type is not [`Parse`], instead having two distinct methods
/// for parsing "inner" vs "outer" attributes.
Expand All @@ -158,42 +194,6 @@ fn derive_table_helper_attr() -> Attribute {
.unwrap()
}

#[proc_macro_attribute]
pub fn table(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
// put this on the struct so we don't get unknown attribute errors
let derive_table_helper: syn::Attribute = derive_table_helper_attr();

ok_or_compile_error(|| {
let item = TokenStream::from(item);
let mut derive_input: syn::DeriveInput = syn::parse2(item.clone())?;

// Add `derive(__TableHelper)` only if it's not already in the attributes of the `derive_input.`
// If multiple `#[table]` attributes are applied to the same `struct` item,
// this will ensure that we don't emit multiple conflicting implementations
// for traits like `SpacetimeType`, `Serialize` and `Deserialize`.
//
// We need to push at the end, rather than the beginning,
// because rustc expands attribute macros (including derives) top-to-bottom,
// and we need *all* `#[table]` attributes *before* the `derive(__TableHelper)`.
// This way, the first `table` will insert a `derive(__TableHelper)`,
// and all subsequent `#[table]`s on the same `struct` will see it,
// and not add another.
//
// Note, thank goodness, that `syn`'s `PartialEq` impls (provided with the `extra-traits` feature)
// skip any [`Span`]s contained in the items,
// thereby comparing for syntactic rather than structural equality. This shouldn't matter,
// since we expect that the `derive_table_helper` will always have the same [`Span`]s,
// but it's nice to know.
if !derive_input.attrs.contains(&derive_table_helper) {
derive_input.attrs.push(derive_table_helper);
}

let args = table::TableArgs::parse(args.into(), &derive_input.ident)?;
let generated = table::table_impl(args, &derive_input)?;
Ok(TokenStream::from_iter([quote!(#derive_input), generated]))
})
}

/// Special alias for `derive(SpacetimeType)`, aka [`schema_type`], for use by [`table`].
///
/// Provides helper attributes for `#[spacetimedb::table]`, so that we don't get unknown attribute errors.
Expand Down Expand Up @@ -291,7 +291,7 @@ pub fn client_visibility_filter(args: StdTokenStream, item: StdTokenStream) -> S
#item

const _: () = {
#[export_name = #register_rls_symbol]
#[unsafe(export_name = #register_rls_symbol)]
extern "C" fn __register_client_visibility_filter() {
spacetimedb::rt::register_row_level_security(#rls_ident.sql_text())
}
Expand Down
2 changes: 1 addition & 1 deletion crates/bindings-macro/src/procedure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub(crate) fn procedure_impl(_args: ProcedureArgs, original_function: &ItemFn) -
let lifetime_where_clause = &lifetime_params.where_clause;

let generated_describe_function = quote! {
#[export_name = #register_describer_symbol]
#[unsafe(export_name = #register_describer_symbol)]
pub extern "C" fn __register_describer() {
spacetimedb::rt::register_procedure::<_, _, #func_name>(#func_name)
}
Expand Down
6 changes: 3 additions & 3 deletions crates/bindings-macro/src/reducer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ pub(crate) fn assert_only_lifetime_generics(original_function: &ItemFn, function
syn::GenericParam::Type(_) => {
return Err(err(format!(
"type parameters are not allowed on {function_kind_plural}"
)))
)));
}
syn::GenericParam::Const(_) => {
return Err(err(format!(
"const parameters are not allowed on {function_kind_plural}"
)))
)));
}
}
}
Expand Down Expand Up @@ -135,7 +135,7 @@ pub(crate) fn reducer_impl(args: ReducerArgs, original_function: &ItemFn) -> syn
let lt_where_clause = &lt_params.where_clause;

let generated_describe_function = quote! {
#[export_name = #register_describer_symbol]
#[unsafe(export_name = #register_describer_symbol)]
pub extern "C" fn __register_describer() {
spacetimedb::rt::register_reducer::<_, #func_name>(#func_name)
}
Expand Down
18 changes: 9 additions & 9 deletions crates/bindings-macro/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,14 +784,14 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
}
}

if let Some(default_value) = &default_value {
if auto_inc.is_some() || primary_key.is_some() || unique.is_some() {
return Err(syn::Error::new(
default_value.span(),
"invalid combination: auto_inc, unique index or primary key cannot have a default value",
));
};
}
if let Some(default_value) = &default_value
&& (auto_inc.is_some() || primary_key.is_some() || unique.is_some())
{
return Err(syn::Error::new(
default_value.span(),
"invalid combination: auto_inc, unique index or primary key cannot have a default value",
));
};

let column = Column {
index: col_num,
Expand Down Expand Up @@ -1038,7 +1038,7 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
let register_describer_symbol = format!("__preinit__20_register_describer_{table_ident}");

let describe_table_func = quote! {
#[export_name = #register_describer_symbol]
#[unsafe(export_name = #register_describer_symbol)]
extern "C" fn __register_describer() {
spacetimedb::rt::register_table::<#tablehandle_ident>()
}
Expand Down
Loading
Loading