hydracache_db/entity.rs
1use hydracache::CacheKeyBuilder;
2
3/// Static cache metadata for a domain entity.
4///
5/// Derive or implement this trait when you want domain-shaped cache calls
6/// without repeating entity and collection names at every query site.
7///
8/// # Example
9///
10/// ```rust
11/// use hydracache_db::{CacheEntity, HydraCacheEntity};
12///
13/// #[derive(HydraCacheEntity)]
14/// #[hydracache(entity = "user", collection = "users")]
15/// struct User {
16/// #[hydracache(id)]
17/// id: i64,
18/// }
19///
20/// assert_eq!(User::cache_key_for(&42), "user:42");
21/// assert_eq!(User::entity_tag_for(&42), "user:42");
22/// assert_eq!(User::collection_tag(), Some("users".to_owned()));
23/// ```
24///
25/// Use `#[hydracache(id = Type)]` on the struct when the id type is generated
26/// or otherwise not represented by one named field.
27pub trait CacheEntity {
28 /// Identifier type used to build entity keys and tags.
29 type Id: ToString;
30
31 /// Stable entity segment used in keys and entity tags.
32 const ENTITY: &'static str;
33
34 /// Optional collection tag for broader invalidation groups.
35 const COLLECTION: Option<&'static str>;
36
37 /// Build the logical cache key for this entity id.
38 fn cache_key_for(id: &Self::Id) -> String {
39 CacheKeyBuilder::new()
40 .entity(Self::ENTITY, id.to_string())
41 .build_string()
42 }
43
44 /// Build the entity invalidation tag for this id.
45 fn entity_tag_for(id: &Self::Id) -> String {
46 Self::cache_key_for(id)
47 }
48
49 /// Build the optional collection invalidation tag.
50 fn collection_tag() -> Option<String> {
51 Self::COLLECTION.map(|collection| CacheKeyBuilder::from_segment(collection).build_string())
52 }
53}