@@ -15,7 +15,7 @@ use bitflags::Flags;
15
15
use module:: { derive_deserialize, derive_satstype, derive_serialize} ;
16
16
use proc_macro:: TokenStream as StdTokenStream ;
17
17
use proc_macro2:: { Span , TokenStream } ;
18
- use quote:: { format_ident, quote, quote_spanned, TokenStreamExt } ;
18
+ use quote:: { format_ident, quote, quote_spanned} ;
19
19
use spacetimedb_primitives:: ColumnAttribute ;
20
20
use std:: collections:: HashMap ;
21
21
use std:: time:: Duration ;
@@ -433,23 +433,15 @@ fn reducer_type_check(item: &syn::DeriveInput, reducer_name: &Path) -> TokenStre
433
433
}
434
434
435
435
struct IndexArg {
436
- name : Option < Ident > ,
436
+ #[ allow( unused) ]
437
+ name : Ident ,
437
438
kind : IndexType ,
438
439
}
439
440
440
441
enum IndexType {
441
442
BTree { columns : Vec < Ident > } ,
442
443
}
443
444
444
- impl quote:: ToTokens for IndexType {
445
- fn to_tokens ( & self , tokens : & mut TokenStream ) {
446
- let kind = match self {
447
- IndexType :: BTree { .. } => "BTree" ,
448
- } ;
449
- tokens. append ( Ident :: new ( kind, Span :: call_site ( ) ) )
450
- }
451
- }
452
-
453
445
impl TableArgs {
454
446
fn parse ( input : TokenStream ) -> syn:: Result < Self > {
455
447
let mut specified_access = false ;
@@ -508,6 +500,7 @@ impl IndexArg {
508
500
} ) ;
509
501
Ok ( ( ) )
510
502
} ) ?;
503
+ let name = name. ok_or_else ( || meta. error ( "missing index name, e.g. name = my_index" ) ) ?;
511
504
let kind = algo. ok_or_else ( || meta. error ( "missing index algorithm, e.g., `btree(columns = [col1, col2])`" ) ) ?;
512
505
513
506
Ok ( IndexArg { name, kind } )
@@ -536,7 +529,7 @@ impl IndexArg {
536
529
Ok ( IndexType :: BTree { columns } )
537
530
}
538
531
539
- /// Parses an inline `#[index(btree | hash )]` attribute on a field.
532
+ /// Parses an inline `#[index(btree)]` attribute on a field.
540
533
fn parse_index_attr ( field : & Ident , attr : & syn:: Attribute ) -> syn:: Result < Self > {
541
534
let mut kind = None ;
542
535
attr. parse_nested_meta ( |meta| {
@@ -551,22 +544,37 @@ impl IndexArg {
551
544
Ok ( ( ) )
552
545
} ) ?;
553
546
let kind = kind. ok_or_else ( || syn:: Error :: new_spanned ( & attr. meta , "must specify kind of index (`btree`)" ) ) ?;
554
- Ok ( IndexArg { kind, name : None } )
547
+ let name = field. clone ( ) ;
548
+ Ok ( IndexArg { kind, name } )
555
549
}
556
550
557
- /// Returns the name the index will have
558
- /// assuming the table is named `table_name`
559
- /// and that the columns of the table are in `cols`.
560
- fn normalized_name ( & self , table_name : & str , cols : & [ & Column ] ) -> String {
561
- self . name
562
- . as_ref ( )
563
- . map ( |s| s. to_string ( ) )
564
- . unwrap_or_else ( || match & self . kind {
565
- IndexType :: BTree { .. } => ( [ "btree" , table_name] . into_iter ( ) )
551
+ fn to_index_desc ( & self , table_name : & str , cols : & [ Column ] ) -> Result < TokenStream , syn:: Error > {
552
+ match & self . kind {
553
+ IndexType :: BTree { columns } => {
554
+ let cols = columns
555
+ . iter ( )
556
+ . map ( |ident| {
557
+ let col = cols
558
+ . iter ( )
559
+ . find ( |col| col. field . ident == Some ( ident) )
560
+ . ok_or_else ( || syn:: Error :: new ( ident. span ( ) , "not a column of the table" ) ) ?;
561
+ Ok ( col)
562
+ } )
563
+ . collect :: < syn:: Result < Vec < _ > > > ( ) ?;
564
+
565
+ let name = ( [ "btree" , table_name] . into_iter ( ) )
566
566
. chain ( cols. iter ( ) . map ( |col| col. field . name . as_deref ( ) . unwrap ( ) ) )
567
567
. collect :: < Vec < _ > > ( )
568
- . join ( "_" ) ,
569
- } )
568
+ . join ( "_" ) ;
569
+
570
+ let col_ids = cols. iter ( ) . map ( |col| col. index ) ;
571
+ Ok ( quote ! ( spacetimedb:: IndexDesc {
572
+ name: #name,
573
+ ty: spacetimedb:: spacetimedb_lib:: db:: raw_def:: IndexType :: BTree ,
574
+ col_ids: & [ #( #col_ids) , * ] ,
575
+ } ) )
576
+ }
577
+ }
570
578
}
571
579
}
572
580
@@ -601,13 +609,13 @@ impl IndexArg {
601
609
/// system; `pub struct` or `pub(crate) struct` do not affect the table visibility, only
602
610
/// the visibility of the items in your own source code.
603
611
///
604
- /// * `index(name = "..." , btree | hash = [a, b, c])`
612
+ /// * `index(name = my_index , btree(columns = [a, b, c]) )`
605
613
///
606
614
/// You can specify an index on 1 or more of the table's columns with the above syntax.
607
- /// You can also just put `#[index(btree | hash )]` on the field itself if you only need
615
+ /// You can also just put `#[index(btree)]` on the field itself if you only need
608
616
/// a single-column attribute; see column attributes below.
609
617
///
610
- /// * `name = "..." `
618
+ /// * `name = my_table `
611
619
///
612
620
/// Specify the name of the table in the database, if you want it to be different from
613
621
/// the name of the struct.
@@ -633,7 +641,7 @@ impl IndexArg {
633
641
///
634
642
/// Similar to `#[unique]`, but generates additional CRUD methods.
635
643
///
636
- /// * `#[index(btree | hash )]`
644
+ /// * `#[index(btree)]`
637
645
///
638
646
/// Creates a single-column index with the specified algorithm.
639
647
///
@@ -778,29 +786,11 @@ fn table_impl(mut args: TableArgs, mut item: MutItem<syn::DeriveInput>) -> syn::
778
786
columns. push ( column) ;
779
787
}
780
788
781
- let mut indexes = vec ! [ ] ;
782
-
783
- for index in args. indices {
784
- let IndexType :: BTree { columns : cols } = & index. kind ;
785
- let cols = cols
786
- . iter ( )
787
- . map ( |ident| {
788
- let col = columns
789
- . iter ( )
790
- . find ( |col| col. field . ident == Some ( ident) )
791
- . ok_or_else ( || syn:: Error :: new ( ident. span ( ) , "not a column of the table" ) ) ?;
792
- Ok ( col)
793
- } )
794
- . collect :: < syn:: Result < Vec < _ > > > ( ) ?;
795
- let name = index. normalized_name ( & table_name, & cols) ;
796
- let col_ids = cols. iter ( ) . map ( |col| col. index ) ;
797
- let ty = & index. kind ;
798
- indexes. push ( quote ! ( spacetimedb:: IndexDesc {
799
- name: #name,
800
- ty: spacetimedb:: spacetimedb_lib:: db:: raw_def:: IndexType :: #ty,
801
- col_ids: & [ #( #col_ids) , * ] ,
802
- } ) ) ;
803
- }
789
+ let indexes = args
790
+ . indices
791
+ . iter ( )
792
+ . map ( |index| index. to_index_desc ( & table_name, & columns) )
793
+ . collect :: < syn:: Result < Vec < _ > > > ( ) ?;
804
794
805
795
let ( unique_columns, nonunique_columns) : ( Vec < _ > , Vec < _ > ) =
806
796
columns. iter ( ) . partition ( |x| x. attr . contains ( ColumnAttribute :: UNIQUE ) ) ;
0 commit comments