Skip to content

Commit

Permalink
Sync some part of the cache types (cached, io_cached and once)
Browse files Browse the repository at this point in the history
- Add no_cache function to io_cached and once
- Add `attributes` to prime function of all types
- Add `generics` to some/all missing places
- Remove some duplicate codes
  • Loading branch information
omid committed Aug 8, 2024
1 parent a953546 commit 7469f0d
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 92 deletions.
181 changes: 102 additions & 79 deletions cached_proc_macro/src/io_cached.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ pub fn io_cached(args: TokenStream, input: TokenStream) -> TokenStream {
let inputs = signature.inputs.clone();
let output = signature.output.clone();
let asyncness = signature.asyncness;
let generics = signature.generics.clone();

let input_tys = get_input_types(&inputs);

let input_names = get_input_names(&inputs);

// pull out the output type
Expand Down Expand Up @@ -407,26 +407,13 @@ pub fn io_cached(args: TokenStream, input: TokenStream) -> TokenStream {
(set_cache_block, return_cache_block)
};

let do_set_return_block = if asyncness.is_some() {
quote! {
// run the function and cache the result
async fn inner(#inputs) #output #body;
let result = inner(#(#input_names),*).await;
let cache = &#cache_ident.get_or_init(init).await;
#set_cache_block
result
}
} else {
quote! {
// run the function and cache the result
fn inner(#inputs) #output #body;
let result = inner(#(#input_names),*);
let cache = &#cache_ident;
#set_cache_block
result
}
let set_cache_and_return = quote! {
#set_cache_block
result
};

let no_cache_fn_ident = Ident::new(&format!("{}_no_cache", &fn_ident), fn_ident.span());

let signature_no_muts = get_mut_signature(signature);

// create a signature for the cache-priming function
Expand All @@ -436,23 +423,14 @@ pub fn io_cached(args: TokenStream, input: TokenStream) -> TokenStream {

// make cached static, cached function and prime cached function doc comments
let cache_ident_doc = format!("Cached static for the [`{}`] function.", fn_ident);
let no_cache_fn_indent_doc = format!("Origin of the cached function [`{}`].", fn_ident);
let prime_fn_indent_doc = format!("Primes the cached function [`{}`].", fn_ident);
let cache_fn_doc_extra = format!(
"This is a cached function that uses the [`{}`] cached static.",
cache_ident
);
fill_in_attributes(&mut attributes, cache_fn_doc_extra);

let async_trait = if asyncness.is_some() && !args.disk {
quote! {
use cached::IOCachedAsync;
}
} else {
quote! {
use cached::IOCached;
}
};

let async_cache_get_return = if asyncness.is_some() && !args.disk {
quote! {
if let Some(result) = cache.cache_get(&key).await.map_err(#map_error)? {
Expand All @@ -466,62 +444,107 @@ pub fn io_cached(args: TokenStream, input: TokenStream) -> TokenStream {
}
}
};
// put it all together
let expanded = if asyncness.is_some() {
quote! {
// Cached static
#[doc = #cache_ident_doc]

let use_trait = if asyncness.is_some() && !args.disk {
quote! { use cached::IOCachedAsync; }
} else {
quote! { use cached::IOCached; }
};

let init;
let function_no_cache;
let function_call;
let ty;
let logic;
if asyncness.is_some() {
init = quote! {
let init = || async { #cache_create };
};

function_no_cache = quote! {
async fn #no_cache_fn_ident #generics (#inputs) #output #body
};

function_call = quote! {
let result = #no_cache_fn_ident(#(#input_names),*).await;
};

ty = quote! {
#visibility static #cache_ident: ::cached::async_sync::OnceCell<#cache_ty> = ::cached::async_sync::OnceCell::const_new();
// Cached function
#(#attributes)*
#visibility #signature_no_muts {
let init = || async { #cache_create };
#async_trait
let key = #key_convert_block;
{
// check if the result is cached
let cache = &#cache_ident.get_or_init(init).await;
#async_cache_get_return
}
#do_set_return_block
}
// Prime cached function
#[doc = #prime_fn_indent_doc]
#[allow(dead_code)]
#visibility #prime_sig {
#async_trait
let init = || async { #cache_create };
let key = #key_convert_block;
#do_set_return_block
};

logic = quote! {
let cache = &#cache_ident.get_or_init(init).await;
#async_cache_get_return
};
} else {
init = quote! {};

function_no_cache = quote! {
fn #no_cache_fn_ident #generics (#inputs) #output #body
};

function_call = quote! {
let result = #no_cache_fn_ident(#(#input_names),*);
};

ty = quote! {
#visibility static #cache_ident: ::cached::once_cell::sync::Lazy<#cache_ty> = ::cached::once_cell::sync::Lazy::new(|| #cache_create);
};

logic = quote! {
let cache = &#cache_ident;
if let Some(result) = cache.cache_get(&key).map_err(#map_error)? {
#return_cache_block
}
};
}

let do_set_return_block = if asyncness.is_some() {
quote! {
// run the function and cache the result
#function_call
let cache = &#cache_ident.get_or_init(init).await;
#set_cache_and_return
}
} else {
quote! {
// Cached static
#[doc = #cache_ident_doc]
#visibility static #cache_ident: ::cached::once_cell::sync::Lazy<#cache_ty> = ::cached::once_cell::sync::Lazy::new(|| #cache_create);
// Cached function
#(#attributes)*
#visibility #signature_no_muts {
use cached::IOCached;
let key = #key_convert_block;
{
// check if the result is cached
let cache = &#cache_ident;
if let Some(result) = cache.cache_get(&key).map_err(#map_error)? {
#return_cache_block
}
}
#do_set_return_block
}
// Prime cached function
#[doc = #prime_fn_indent_doc]
#[allow(dead_code)]
#visibility #prime_sig {
use cached::IOCached;
let key = #key_convert_block;
#do_set_return_block
// run the function and cache the result
#function_call
let cache = &#cache_ident;
#set_cache_and_return
}
};

// put it all together
let expanded = quote! {
// Cached static
#[doc = #cache_ident_doc]
#ty
// No cache function (origin of the cached function)
#[doc = #no_cache_fn_indent_doc]
#visibility #function_no_cache
// Cached function
#(#attributes)*
#visibility #signature_no_muts {
#init
#use_trait
let key = #key_convert_block;
{
// check if the result is cached
#logic
}
#do_set_return_block
}
// Prime cached function
#[doc = #prime_fn_indent_doc]
#[allow(dead_code)]
#(#attributes)*
#visibility #prime_sig {
#use_trait
#init
let key = #key_convert_block;
#do_set_return_block
}
};

Expand Down
37 changes: 24 additions & 13 deletions cached_proc_macro/src/once.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ pub fn once(args: TokenStream, input: TokenStream) -> TokenStream {
let inputs = signature.inputs.clone();
let output = signature.output.clone();
let asyncness = signature.asyncness;
let generics = signature.generics.clone();

// pull out the names and types of the function inputs
let input_names = get_input_names(&inputs);

// pull out the output type
Expand Down Expand Up @@ -89,13 +89,9 @@ pub fn once(args: TokenStream, input: TokenStream) -> TokenStream {
let (set_cache_block, return_cache_block) = match (&args.result, &args.option) {
(false, false) => {
let set_cache_block = if args.time.is_some() {
quote! {
*cached = Some((now, result.clone()));
}
quote! { *cached = Some((now, result.clone())); }
} else {
quote! {
*cached = Some(result.clone());
}
quote! { *cached = Some(result.clone()); }
};

let return_cache_block = if args.with_cached_flag {
Expand Down Expand Up @@ -159,8 +155,12 @@ pub fn once(args: TokenStream, input: TokenStream) -> TokenStream {
#set_cache_block
result
};

let no_cache_fn_ident = Ident::new(&format!("{}_no_cache", &fn_ident), fn_ident.span());

let r_lock;
let w_lock;
let function_no_cache;
let function_call;
let ty;
if asyncness.is_some() {
Expand All @@ -174,10 +174,12 @@ pub fn once(args: TokenStream, input: TokenStream) -> TokenStream {
let mut cached = #cache_ident.read().await;
};

function_no_cache = quote! {
async fn #no_cache_fn_ident #generics (#inputs) #output #body
};

function_call = quote! {
// run the function and cache the result
async fn inner(#inputs) #output #body;
let result = inner(#(#input_names),*).await;
let result = #no_cache_fn_ident(#(#input_names),*).await;
};

ty = quote! {
Expand All @@ -194,10 +196,12 @@ pub fn once(args: TokenStream, input: TokenStream) -> TokenStream {
let mut cached = #cache_ident.read().unwrap();
};

function_no_cache = quote! {
fn #no_cache_fn_ident #generics (#inputs) #output #body
};

function_call = quote! {
// run the function and cache the result
fn inner(#inputs) #output #body;
let result = inner(#(#input_names),*);
let result = #no_cache_fn_ident(#(#input_names),*);
};

ty = quote! {
Expand All @@ -206,7 +210,9 @@ pub fn once(args: TokenStream, input: TokenStream) -> TokenStream {
}

let prime_do_set_return_block = quote! {
// try to get a lock first
#w_lock
// run the function and cache the result
#function_call
#set_cache_and_return
};
Expand Down Expand Up @@ -247,6 +253,7 @@ pub fn once(args: TokenStream, input: TokenStream) -> TokenStream {

// make cached static, cached function and prime cached function doc comments
let cache_ident_doc = format!("Cached static for the [`{}`] function.", fn_ident);
let no_cache_fn_indent_doc = format!("Origin of the cached function [`{}`].", fn_ident);
let prime_fn_indent_doc = format!("Primes the cached function [`{}`].", fn_ident);
let cache_fn_doc_extra = format!(
"This is a cached function that uses the [`{}`] cached static.",
Expand All @@ -259,6 +266,9 @@ pub fn once(args: TokenStream, input: TokenStream) -> TokenStream {
// Cached static
#[doc = #cache_ident_doc]
#ty
// No cache function (origin of the cached function)
#[doc = #no_cache_fn_indent_doc]
#visibility #function_no_cache
// Cached function
#(#attributes)*
#visibility #signature_no_muts {
Expand All @@ -268,6 +278,7 @@ pub fn once(args: TokenStream, input: TokenStream) -> TokenStream {
// Prime cached function
#[doc = #prime_fn_indent_doc]
#[allow(dead_code)]
#(#attributes)*
#visibility #prime_sig {
let now = ::cached::web_time::Instant::now();
#prime_do_set_return_block
Expand Down

0 comments on commit 7469f0d

Please sign in to comment.