Skip to main content

hydracache_macros/
lib.rs

1use proc_macro::TokenStream;
2use syn::{parse_macro_input, DeriveInput};
3
4mod cacheable;
5mod config;
6mod entity;
7mod paths;
8mod policy;
9
10/// Derive `CacheEntity` metadata for database result-cache helpers.
11///
12/// # Example
13///
14/// ```rust,ignore
15/// use hydracache_db::{CacheEntity, HydraCacheEntity};
16///
17/// #[derive(HydraCacheEntity)]
18/// #[hydracache(entity = "user", collection = "users", id = i64)]
19/// struct User {
20///     id: i64,
21///     name: String,
22/// }
23///
24/// assert_eq!(User::cache_key_for(&42), "user:42");
25/// ```
26#[proc_macro_derive(HydraCacheEntity, attributes(hydracache))]
27pub fn derive_hydracache_entity(input: TokenStream) -> TokenStream {
28    entity::expand(parse_macro_input!(input as DeriveInput))
29        .unwrap_or_else(syn::Error::into_compile_error)
30        .into()
31}
32
33/// Build a `QueryCachePolicy` with less boilerplate.
34///
35/// # Example
36///
37/// ```rust,ignore
38/// use hydracache_db::{query_cache_policy, QueryCachePolicy};
39///
40/// let user_id = 42_i64;
41/// let policy = query_cache_policy!(
42///     name = "load-user",
43///     entity = User,
44///     id = user_id,
45///     ttl_secs = 60,
46/// );
47/// ```
48#[proc_macro]
49pub fn query_cache_policy(input: TokenStream) -> TokenStream {
50    policy::expand(input.into())
51        .unwrap_or_else(syn::Error::into_compile_error)
52        .into()
53}
54
55/// Cache an ordinary async loader with explicit local-cache metadata.
56///
57/// # Example
58///
59/// ```rust,ignore
60/// use hydracache::{cacheable, HydraCache};
61///
62/// let cache = HydraCache::local().build();
63///
64/// let value = cacheable!(
65///     cache = cache,
66///     key = "expensive:42",
67///     tag = "expensive",
68///     ttl_secs = 60,
69///     load = || async { Ok::<_, std::io::Error>(42_u64) },
70/// )
71/// .await?;
72/// ```
73#[proc_macro]
74pub fn cacheable(input: TokenStream) -> TokenStream {
75    cacheable::expand(input.into())
76        .unwrap_or_else(syn::Error::into_compile_error)
77        .into()
78}