Skip to content

Commit 48e6689

Browse files
committed
[release/v1.7.0]: Revert "Make name a required parameter of view macro (#3480)"
This reverts commit 8f11ac8.
1 parent 0012405 commit 48e6689

File tree

7 files changed

+129
-140
lines changed

7 files changed

+129
-140
lines changed

crates/bindings-macro/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ pub fn reducer(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
125125
#[proc_macro_attribute]
126126
pub fn view(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
127127
cvt_attr::<ItemFn>(args, item, quote!(), |args, original_function| {
128-
let args = view::ViewArgs::parse(args, &original_function.sig.ident)?;
128+
let args = view::ViewArgs::parse(args)?;
129129
view::view_impl(args, original_function)
130130
})
131131
}

crates/bindings-macro/src/view.rs

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,55 @@
1-
use heck::ToSnakeCase;
2-
use proc_macro2::{Ident, Span, TokenStream};
1+
use proc_macro2::{Span, TokenStream};
32
use quote::quote;
4-
use syn::ext::IdentExt;
53
use syn::parse::Parser;
64
use syn::{FnArg, ItemFn};
75

86
use crate::sym;
9-
use crate::util::{check_duplicate_msg, match_meta};
7+
use crate::util::{ident_to_litstr, match_meta};
108

119
pub(crate) struct ViewArgs {
12-
name: Ident,
1310
#[allow(unused)]
1411
public: bool,
1512
}
1613

1714
impl ViewArgs {
18-
/// Parse `#[view(name = ..., public)]` where both `name` and `public` are required.
19-
pub(crate) fn parse(input: TokenStream, func_ident: &Ident) -> syn::Result<Self> {
20-
let mut name = None;
21-
let mut public = None;
15+
/// Parse `#[view(public)]` where `public` is required.
16+
pub(crate) fn parse(input: TokenStream) -> syn::Result<Self> {
17+
if input.is_empty() {
18+
return Err(syn::Error::new(
19+
Span::call_site(),
20+
"views must be declared as `#[view(public)]`; `public` is required",
21+
));
22+
}
23+
let mut public = false;
2224
syn::meta::parser(|meta| {
2325
match_meta!(match meta {
24-
sym::name => {
25-
check_duplicate_msg(&name, &meta, "`name` already specified")?;
26-
name = Some(meta.value()?.parse()?);
27-
}
2826
sym::public => {
29-
check_duplicate_msg(&public, &meta, "`public` already specified")?;
30-
public = Some(());
27+
if public {
28+
return Err(syn::Error::new(
29+
Span::call_site(),
30+
"duplicate attribute argument: `public`",
31+
));
32+
}
33+
public = true;
3134
}
3235
});
3336
Ok(())
3437
})
3538
.parse2(input)?;
36-
let name = name.ok_or_else(|| {
37-
let view = func_ident.to_string().to_snake_case();
38-
syn::Error::new(
39+
if !public {
40+
return Err(syn::Error::new(
3941
Span::call_site(),
40-
format_args!("must specify view name, e.g. `#[spacetimedb::view(name = {view})]"),
41-
)
42-
})?;
43-
let () = public
44-
.ok_or_else(|| syn::Error::new(Span::call_site(), "views must be `public`, e.g. `#[view(public)]`"))?;
45-
Ok(Self { name, public: true })
42+
"views must be declared as `#[view(public)]`; `public` is required",
43+
));
44+
}
45+
Ok(Self { public })
4646
}
4747
}
4848

49-
pub(crate) fn view_impl(args: ViewArgs, original_function: &ItemFn) -> syn::Result<TokenStream> {
50-
let vis = &original_function.vis;
49+
pub(crate) fn view_impl(_args: ViewArgs, original_function: &ItemFn) -> syn::Result<TokenStream> {
5150
let func_name = &original_function.sig.ident;
52-
let view_ident = args.name;
53-
let view_name = view_ident.unraw().to_string();
51+
let view_name = ident_to_litstr(func_name);
52+
let vis = &original_function.vis;
5453

5554
for param in &original_function.sig.generics.params {
5655
let err = |msg| syn::Error::new_spanned(param, msg);
@@ -117,7 +116,7 @@ pub(crate) fn view_impl(args: ViewArgs, original_function: &ItemFn) -> syn::Resu
117116
}
118117
};
119118

120-
let register_describer_symbol = format!("__preinit__20_register_describer_{}", view_name);
119+
let register_describer_symbol = format!("__preinit__20_register_describer_{}", view_name.value());
121120

122121
let lt_params = &original_function.sig.generics;
123122
let lt_where_clause = &lt_params.where_clause;

crates/bindings/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -819,25 +819,25 @@ pub use spacetimedb_bindings_macro::procedure;
819819
/// }
820820
///
821821
/// // A view that selects at most one row from a table
822-
/// #[view(name = my_player, public)]
822+
/// #[view(public)]
823823
/// fn my_player(ctx: &ViewContext) -> Option<Player> {
824824
/// ctx.db.player().identity().find(ctx.sender)
825825
/// }
826826
///
827827
/// // An example of column projection
828-
/// #[view(name = my_player_id, public)]
828+
/// #[view(public)]
829829
/// fn my_player_id(ctx: &ViewContext) -> Option<PlayerId> {
830830
/// ctx.db.player().identity().find(ctx.sender).map(|Player { id, .. }| PlayerId { id })
831831
/// }
832832
///
833833
/// // An example of a parameterized view
834-
/// #[view(name = players_at_level, public)]
834+
/// #[view(public)]
835835
/// fn players_at_level(ctx: &AnonymousViewContext, level: u32) -> Vec<Player> {
836836
/// ctx.db.player().level().filter(level).collect()
837837
/// }
838838
///
839839
/// // An example that is analogous to a semijoin in sql
840-
/// #[view(name = players_at_coordinates, public)]
840+
/// #[view(public)]
841841
/// fn players_at_coordinates(ctx: &AnonymousViewContext, x: u64, y: u64) -> Vec<Player> {
842842
/// ctx
843843
/// .db
@@ -849,7 +849,7 @@ pub use spacetimedb_bindings_macro::procedure;
849849
/// }
850850
///
851851
/// // An example of a join that combines fields from two different tables
852-
/// #[view(name = players_with_coordinates, public)]
852+
/// #[view(public)]
853853
/// fn players_with_coordinates(ctx: &AnonymousViewContext, x: u64, y: u64) -> Vec<PlayerAndLocation> {
854854
/// ctx
855855
/// .db

crates/bindings/tests/ui/views.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -72,68 +72,62 @@ struct Player {
7272

7373
struct NotSpacetimeType {}
7474

75-
/// Private views not allowed; must be `#[view(public, ...)]`
76-
#[view(name = view_def_no_public)]
75+
/// Private views not allowed; must be `#[view(public)]`
76+
#[view]
7777
fn view_def_no_public(_: &ViewContext) -> Vec<Player> {
7878
vec![]
7979
}
8080

8181
/// Duplicate `public`
82-
#[view(name = view_def_dup_public, public, public)]
83-
fn view_def_dup_public() -> Vec<Player> {
84-
vec![]
85-
}
86-
87-
/// Duplicate `name`
88-
#[view(name = view_def_dup_name, name = view_def_dup_name, public)]
89-
fn view_def_dup_name() -> Vec<Player> {
82+
#[view(public, public)]
83+
fn view_def_duplicate_attribute_arg() -> Vec<Player> {
9084
vec![]
9185
}
9286

9387
/// Unsupported attribute arg
94-
#[view(name = view_def_unsupported_arg, public, anonymous)]
95-
fn view_def_unsupported_arg() -> Vec<Player> {
88+
#[view(public, anonymous)]
89+
fn view_def_unsupported_attribute_arg() -> Vec<Player> {
9690
vec![]
9791
}
9892

9993
/// A `ViewContext` is required
100-
#[view(name = view_def_no_context, public)]
94+
#[view(public)]
10195
fn view_def_no_context() -> Vec<Player> {
10296
vec![]
10397
}
10498

10599
/// A `ViewContext` is required
106-
#[view(name = view_def_wrong_context, public)]
100+
#[view(public)]
107101
fn view_def_wrong_context(_: &ReducerContext) -> Vec<Player> {
108102
vec![]
109103
}
110104

111105
/// Must pass the `ViewContext` by ref
112-
#[view(name = view_def_pass_context_by_value, public)]
106+
#[view(public)]
113107
fn view_def_pass_context_by_value(_: ViewContext) -> Vec<Player> {
114108
vec![]
115109
}
116110

117111
/// The view context must be the first parameter
118-
#[view(name = view_def_wrong_context_position, public)]
112+
#[view(public)]
119113
fn view_def_wrong_context_position(_: &u32, _: &ViewContext) -> Vec<Player> {
120114
vec![]
121115
}
122116

123117
/// Must return `Vec<T>` or `Option<T>` where `T` is a SpacetimeType
124-
#[view(name = view_def_no_return, public)]
118+
#[view(public)]
125119
fn view_def_no_return(_: &ViewContext) {}
126120

127121
/// Must return `Vec<T>` or `Option<T>` where `T` is a SpacetimeType
128-
#[view(name = view_def_wrong_return, public)]
122+
#[view(public)]
129123
fn view_def_wrong_return(_: &ViewContext) -> Player {
130124
Player {
131125
identity: Identity::ZERO,
132126
}
133127
}
134128

135129
/// Must return `Vec<T>` or `Option<T>` where `T` is a SpacetimeType
136-
#[view(name = view_def_returns_not_a_spacetime_type, public)]
130+
#[view(public)]
137131
fn view_def_returns_not_a_spacetime_type(_: &AnonymousViewContext) -> Option<NotSpacetimeType> {
138132
None
139133
}
@@ -150,7 +144,7 @@ struct ScheduledTable {
150144
}
151145

152146
/// Cannot use a view as a scheduled function
153-
#[view(name = scheduled_table_view, public)]
147+
#[view(public)]
154148
fn scheduled_table_view(_: &ViewContext, _args: ScheduledTable) -> Vec<Player> {
155149
vec![]
156150
}

0 commit comments

Comments
 (0)