|
1 | | -use heck::ToSnakeCase; |
2 | | -use proc_macro2::{Ident, Span, TokenStream}; |
| 1 | +use proc_macro2::{Span, TokenStream}; |
3 | 2 | use quote::quote; |
4 | | -use syn::ext::IdentExt; |
5 | 3 | use syn::parse::Parser; |
6 | 4 | use syn::{FnArg, ItemFn}; |
7 | 5 |
|
8 | 6 | use crate::sym; |
9 | | -use crate::util::{check_duplicate_msg, match_meta}; |
| 7 | +use crate::util::{ident_to_litstr, match_meta}; |
10 | 8 |
|
11 | 9 | pub(crate) struct ViewArgs { |
12 | | - name: Ident, |
13 | 10 | #[allow(unused)] |
14 | 11 | public: bool, |
15 | 12 | } |
16 | 13 |
|
17 | 14 | 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; |
22 | 24 | syn::meta::parser(|meta| { |
23 | 25 | match_meta!(match meta { |
24 | | - sym::name => { |
25 | | - check_duplicate_msg(&name, &meta, "`name` already specified")?; |
26 | | - name = Some(meta.value()?.parse()?); |
27 | | - } |
28 | 26 | 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; |
31 | 34 | } |
32 | 35 | }); |
33 | 36 | Ok(()) |
34 | 37 | }) |
35 | 38 | .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( |
39 | 41 | 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 }) |
46 | 46 | } |
47 | 47 | } |
48 | 48 |
|
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> { |
51 | 50 | 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; |
54 | 53 |
|
55 | 54 | for param in &original_function.sig.generics.params { |
56 | 55 | 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 |
117 | 116 | } |
118 | 117 | }; |
119 | 118 |
|
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()); |
121 | 120 |
|
122 | 121 | let lt_params = &original_function.sig.generics; |
123 | 122 | let lt_where_clause = <_params.where_clause; |
|
0 commit comments