@@ -15,7 +15,7 @@ use bitflags::Flags;
1515use module:: { derive_deserialize, derive_satstype, derive_serialize} ;
1616use proc_macro:: TokenStream as StdTokenStream ;
1717use proc_macro2:: { Span , TokenStream } ;
18- use quote:: { format_ident, quote, quote_spanned, TokenStreamExt } ;
18+ use quote:: { format_ident, quote, quote_spanned} ;
1919use spacetimedb_primitives:: ColumnAttribute ;
2020use std:: collections:: HashMap ;
2121use std:: time:: Duration ;
@@ -433,23 +433,15 @@ fn reducer_type_check(item: &syn::DeriveInput, reducer_name: &Path) -> TokenStre
433433}
434434
435435struct IndexArg {
436- name : Option < Ident > ,
436+ #[ allow( unused) ]
437+ name : Ident ,
437438 kind : IndexType ,
438439}
439440
440441enum IndexType {
441442 BTree { columns : Vec < Ident > } ,
442443}
443444
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-
453445impl TableArgs {
454446 fn parse ( input : TokenStream ) -> syn:: Result < Self > {
455447 let mut specified_access = false ;
@@ -508,6 +500,7 @@ impl IndexArg {
508500 } ) ;
509501 Ok ( ( ) )
510502 } ) ?;
503+ let name = name. ok_or_else ( || meta. error ( "missing index name, e.g. name = my_index" ) ) ?;
511504 let kind = algo. ok_or_else ( || meta. error ( "missing index algorithm, e.g., `btree(columns = [col1, col2])`" ) ) ?;
512505
513506 Ok ( IndexArg { name, kind } )
@@ -536,7 +529,7 @@ impl IndexArg {
536529 Ok ( IndexType :: BTree { columns } )
537530 }
538531
539- /// Parses an inline `#[index(btree | hash )]` attribute on a field.
532+ /// Parses an inline `#[index(btree)]` attribute on a field.
540533 fn parse_index_attr ( field : & Ident , attr : & syn:: Attribute ) -> syn:: Result < Self > {
541534 let mut kind = None ;
542535 attr. parse_nested_meta ( |meta| {
@@ -551,22 +544,37 @@ impl IndexArg {
551544 Ok ( ( ) )
552545 } ) ?;
553546 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 } )
555549 }
556550
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 ( ) )
566566 . chain ( cols. iter ( ) . map ( |col| col. field . name . as_deref ( ) . unwrap ( ) ) )
567567 . 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+ }
570578 }
571579}
572580
@@ -601,13 +609,13 @@ impl IndexArg {
601609/// system; `pub struct` or `pub(crate) struct` do not affect the table visibility, only
602610/// the visibility of the items in your own source code.
603611///
604- /// * `index(name = "..." , btree | hash = [a, b, c])`
612+ /// * `index(name = my_index , btree(columns = [a, b, c]) )`
605613///
606614/// 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
608616/// a single-column attribute; see column attributes below.
609617///
610- /// * `name = "..." `
618+ /// * `name = my_table `
611619///
612620/// Specify the name of the table in the database, if you want it to be different from
613621/// the name of the struct.
@@ -633,7 +641,7 @@ impl IndexArg {
633641///
634642/// Similar to `#[unique]`, but generates additional CRUD methods.
635643///
636- /// * `#[index(btree | hash )]`
644+ /// * `#[index(btree)]`
637645///
638646/// Creates a single-column index with the specified algorithm.
639647///
@@ -778,29 +786,11 @@ fn table_impl(mut args: TableArgs, mut item: MutItem<syn::DeriveInput>) -> syn::
778786 columns. push ( column) ;
779787 }
780788
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 < _ > > > ( ) ?;
804794
805795 let ( unique_columns, nonunique_columns) : ( Vec < _ > , Vec < _ > ) =
806796 columns. iter ( ) . partition ( |x| x. attr . contains ( ColumnAttribute :: UNIQUE ) ) ;
0 commit comments