@@ -3,9 +3,18 @@ use darling::ast::NestedMeta;
3
3
use darling:: FromMeta ;
4
4
use proc_macro:: TokenStream ;
5
5
use quote:: quote;
6
+ use std:: cmp:: PartialEq ;
6
7
use syn:: spanned:: Spanned ;
7
8
use syn:: { parse_macro_input, parse_str, Block , Ident , ItemFn , ReturnType , Type } ;
8
9
10
+ #[ derive( Debug , Default , FromMeta , Eq , PartialEq ) ]
11
+ enum SyncWriteMode {
12
+ #[ default]
13
+ Disabled ,
14
+ Default ,
15
+ ByKey ,
16
+ }
17
+
9
18
#[ derive( FromMeta ) ]
10
19
struct MacroArgs {
11
20
#[ darling( default ) ]
@@ -27,9 +36,7 @@ struct MacroArgs {
27
36
#[ darling( default ) ]
28
37
option : bool ,
29
38
#[ darling( default ) ]
30
- sync_writes : bool ,
31
- #[ darling( default ) ]
32
- sync_writes_by_key : bool ,
39
+ sync_writes : SyncWriteMode ,
33
40
#[ darling( default ) ]
34
41
with_cached_flag : bool ,
35
42
#[ darling( default ) ]
@@ -192,16 +199,8 @@ pub fn cached(args: TokenStream, input: TokenStream) -> TokenStream {
192
199
_ => panic ! ( "the result and option attributes are mutually exclusive" ) ,
193
200
} ;
194
201
195
- if args. result_fallback && args. sync_writes {
196
- panic ! ( "the result_fallback and sync_writes attributes are mutually exclusive" ) ;
197
- }
198
-
199
- if args. result_fallback && args. sync_writes_by_key {
200
- panic ! ( "the result_fallback and sync_writes_by_key attributes are mutually exclusive" ) ;
201
- }
202
-
203
- if args. sync_writes && args. sync_writes_by_key {
204
- panic ! ( "the sync_writes and sync_writes_by_key attributes are mutually exclusive" ) ;
202
+ if args. result_fallback && args. sync_writes != SyncWriteMode :: Disabled {
203
+ panic ! ( "result_fallback and sync_writes are mutually exclusive" ) ;
205
204
}
206
205
207
206
let set_cache_and_return = quote ! {
@@ -216,20 +215,19 @@ pub fn cached(args: TokenStream, input: TokenStream) -> TokenStream {
216
215
let function_call;
217
216
let ty;
218
217
if asyncness. is_some ( ) {
219
- lock = if args. sync_writes_by_key {
220
- quote ! {
218
+ lock = match args. sync_writes {
219
+ SyncWriteMode :: ByKey => quote ! {
221
220
let mut locks = #cache_ident. lock( ) . await ;
222
221
let lock = locks
223
222
. entry( key. clone( ) )
224
223
. or_insert_with( || std:: sync:: Arc :: new( :: cached:: async_sync:: Mutex :: new( #cache_create) ) )
225
224
. clone( ) ;
226
225
drop( locks) ;
227
226
let mut cache = lock. lock( ) . await ;
228
- }
229
- } else {
230
- quote ! {
227
+ } ,
228
+ _ => quote ! {
231
229
let mut cache = #cache_ident. lock( ) . await ;
232
- }
230
+ } ,
233
231
} ;
234
232
235
233
function_no_cache = quote ! {
@@ -240,27 +238,25 @@ pub fn cached(args: TokenStream, input: TokenStream) -> TokenStream {
240
238
let result = #no_cache_fn_ident( #( #input_names) , * ) . await ;
241
239
} ;
242
240
243
- ty = if args. sync_writes_by_key {
244
- quote ! {
241
+ ty = match args. sync_writes {
242
+ SyncWriteMode :: ByKey => quote ! {
245
243
#visibility static #cache_ident: :: cached:: once_cell:: sync:: Lazy <:: cached:: async_sync:: Mutex <std:: collections:: HashMap <#cache_key_ty, std:: sync:: Arc <:: cached:: async_sync:: Mutex <#cache_ty>>>>> = :: cached:: once_cell:: sync:: Lazy :: new( || :: cached:: async_sync:: Mutex :: new( std:: collections:: HashMap :: new( ) ) ) ;
246
- }
247
- } else {
248
- quote ! {
244
+ } ,
245
+ _ => quote ! {
249
246
#visibility static #cache_ident: :: cached:: once_cell:: sync:: Lazy <:: cached:: async_sync:: Mutex <#cache_ty>> = :: cached:: once_cell:: sync:: Lazy :: new( || :: cached:: async_sync:: Mutex :: new( #cache_create) ) ;
250
- }
247
+ } ,
251
248
} ;
252
249
} else {
253
- lock = if args. sync_writes_by_key {
254
- quote ! {
250
+ lock = match args. sync_writes {
251
+ SyncWriteMode :: ByKey => quote ! {
255
252
let mut locks = #cache_ident. lock( ) . unwrap( ) ;
256
253
let lock = locks. entry( key. clone( ) ) . or_insert_with( || std:: sync:: Arc :: new( std:: sync:: Mutex :: new( #cache_create) ) ) . clone( ) ;
257
254
drop( locks) ;
258
255
let mut cache = lock. lock( ) . unwrap( ) ;
259
- }
260
- } else {
261
- quote ! {
256
+ } ,
257
+ _ => quote ! {
262
258
let mut cache = #cache_ident. lock( ) . unwrap( ) ;
263
- }
259
+ } ,
264
260
} ;
265
261
266
262
function_no_cache = quote ! {
@@ -271,14 +267,13 @@ pub fn cached(args: TokenStream, input: TokenStream) -> TokenStream {
271
267
let result = #no_cache_fn_ident( #( #input_names) , * ) ;
272
268
} ;
273
269
274
- ty = if args. sync_writes_by_key {
275
- quote ! {
270
+ ty = match args. sync_writes {
271
+ SyncWriteMode :: ByKey => quote ! {
276
272
#visibility static #cache_ident: :: cached:: once_cell:: sync:: Lazy <std:: sync:: Mutex <std:: collections:: HashMap <#cache_key_ty, std:: sync:: Arc <std:: sync:: Mutex <#cache_ty>>>>> = :: cached:: once_cell:: sync:: Lazy :: new( || std:: sync:: Mutex :: new( std:: collections:: HashMap :: new( ) ) ) ;
277
- }
278
- } else {
279
- quote ! {
273
+ } ,
274
+ _ => quote ! {
280
275
#visibility static #cache_ident: :: cached:: once_cell:: sync:: Lazy <std:: sync:: Mutex <#cache_ty>> = :: cached:: once_cell:: sync:: Lazy :: new( || std:: sync:: Mutex :: new( #cache_create) ) ;
281
- }
276
+ } ,
282
277
}
283
278
}
284
279
@@ -290,7 +285,7 @@ pub fn cached(args: TokenStream, input: TokenStream) -> TokenStream {
290
285
#set_cache_and_return
291
286
} ;
292
287
293
- let do_set_return_block = if args. sync_writes_by_key || args . sync_writes {
288
+ let do_set_return_block = if args. sync_writes != SyncWriteMode :: Disabled {
294
289
quote ! {
295
290
#lock
296
291
if let Some ( result) = cache. cache_get( & key) {
0 commit comments