1
1
use crate :: commons:: FnTarget ;
2
2
use crate :: TokenStream1 ;
3
+ use macroific:: prelude:: * ;
4
+ use proc_macro2:: Ident ;
3
5
use quote:: ToTokens ;
4
- use syn:: punctuated:: Punctuated ;
5
6
use syn:: { parse_quote, Error , WherePredicate } ;
6
7
7
- #[ inline]
8
- pub ( super ) fn exec ( spec : TokenStream1 , target : TokenStream1 ) -> TokenStream1 {
9
- match syn:: parse :: < Opts > ( spec) {
10
- Ok ( opts) => match syn:: parse :: < FnTarget > ( target. clone ( ) ) {
11
- Ok ( mut target) => {
12
- opts. extend_target ( & mut target) ;
13
- target. into_token_stream ( ) . into ( )
14
- }
15
- Err ( e) => on_err ( target, e) ,
16
- } ,
17
- Err ( e) => on_err ( target, e) ,
18
- }
19
- }
20
-
21
8
macro_rules! make_opts {
22
- ( $struct_name: ident => { $( $( $opt: ident) |+ => $predicate: ty) ,+ $( , ) ? } ) => {
23
- /// Options list
9
+ ( $struct_name: ident => {
10
+ $( $( $opt: ident) |+ => $predicate: ty) ,+
11
+ $( , [ custom] => {
12
+ $( $extra_opt: ident => $extra_ty: ty) ,+ $( , ) ?
13
+ } ) ? $( , ) ?
14
+ } ) => {
15
+ /// # Options list
24
16
///
25
17
/// | Option | Predicate |
26
18
/// |--------|-----------|
27
19
$( $( #[ doc = concat!( " | `" , stringify!( $opt) , "` | `" , stringify!( $predicate) , "` |" ) ] ) +) +
20
+ ///
21
+ /// # Extras
22
+ ///
23
+ /// | Option | Type |
24
+ /// |--------|-----------|
25
+ $( $( #[ doc = concat!( " | `" , stringify!( $extra_opt) , "` | `" , stringify!( $extra_ty) , "` |" ) ] ) +) +
28
26
#[ derive( :: macroific:: attr_parse:: AttributeOptions ) ]
29
27
pub ( super ) struct $struct_name {
30
- $( $( $opt: :: syn:: punctuated:: Punctuated <proc_macro2:: Ident , :: syn:: Token ![ , ] >) ,+) ,+
28
+ $( $( $opt: :: syn:: punctuated:: Punctuated <proc_macro2:: Ident , :: syn:: Token ![ , ] >, ) +) +
29
+ $( $( $extra_opt: Option <$extra_ty>, ) +) ?
31
30
}
32
31
33
32
impl :: syn:: parse:: Parse for $struct_name {
@@ -42,6 +41,9 @@ macro_rules! make_opts {
42
41
$( $( if !self . $opt. is_empty( ) {
43
42
extend_generics( self . $opt, target, :: quote:: quote!( $predicate) ) ;
44
43
} ) +) +
44
+ $( $( if let Some ( $extra_opt) = self . $extra_opt {
45
+ $extra_opt. extend_target( target) ;
46
+ } ) +) ?
45
47
}
46
48
}
47
49
} ;
@@ -52,18 +54,61 @@ make_opts!(Opts => {
52
54
db_version => crate :: factory:: DBVersion ,
53
55
blocked_cb => :: core:: ops:: FnOnce ( crate :: database:: VersionChangeEvent ) -> crate :: Result <( ) > + ' static ,
54
56
upgrade_cb => :: core:: ops:: FnOnce ( crate :: database:: VersionChangeEvent , crate :: database:: Database ) -> crate :: Result <( ) > + ' static ,
57
+ [ custom] => {
58
+ upgrade_async_cb => UpgradeAsyncCb ,
59
+ } ,
55
60
} ) ;
56
61
62
+ #[ inline]
63
+ pub ( super ) fn exec ( spec : TokenStream1 , target : TokenStream1 ) -> TokenStream1 {
64
+ match syn:: parse :: < Opts > ( spec) {
65
+ Ok ( opts) => match syn:: parse :: < FnTarget > ( target. clone ( ) ) {
66
+ Ok ( mut target) => {
67
+ opts. extend_target ( & mut target) ;
68
+ target. into_token_stream ( ) . into ( )
69
+ }
70
+ Err ( e) => on_err ( target, e) ,
71
+ } ,
72
+ Err ( e) => on_err ( target, e) ,
73
+ }
74
+ }
75
+
76
+ #[ derive( ParseOption ) ]
77
+ struct UpgradeAsyncCb {
78
+ #[ attr_opts( default = false ) ]
79
+ fun : Ident ,
80
+
81
+ #[ attr_opts( default = false ) ]
82
+ fut : Ident ,
83
+ }
84
+
85
+ impl UpgradeAsyncCb {
86
+ fn extend_target ( self , target : & mut FnTarget ) {
87
+ let Self { fun, fut } = self ;
88
+ let wheres = [
89
+ parse_quote ! ( #fun: :: core:: ops:: FnOnce ( crate :: database:: VersionChangeEvent , crate :: database:: Database ) -> #fut + ' static ) ,
90
+ parse_quote ! ( #fut: :: core:: future:: Future <Output = crate :: Result <( ) >> + ' static ) ,
91
+ ] ;
92
+
93
+ target
94
+ . generics_mut ( )
95
+ . make_where_clause ( )
96
+ . predicates
97
+ . extend :: < [ WherePredicate ; 2 ] > ( wheres) ;
98
+ }
99
+ }
100
+
57
101
fn on_err ( mut target : TokenStream1 , e : Error ) -> TokenStream1 {
58
102
let e: TokenStream1 = e. into_compile_error ( ) . into ( ) ;
59
103
target. extend ( e) ;
60
104
target
61
105
}
62
106
63
- fn extend_generics < T , I , P > ( idents : Punctuated < I , P > , target : & mut FnTarget , ext_with : T )
107
+ fn extend_generics < T , Iter , Item > ( idents : Iter , target : & mut FnTarget , ext_with : T )
64
108
where
65
109
T : ToTokens ,
66
- I : ToTokens ,
110
+ Item : ToTokens ,
111
+ Iter : IntoIterator < Item = Item > ,
67
112
{
68
113
let iter = idents
69
114
. into_iter ( )
0 commit comments