Skip to main content

hydracache_db/
entity.rs

1use hydracache::CacheKeyBuilder;
2
3/// Static cache metadata for a domain entity.
4///
5/// Implement this trait manually when you want domain-shaped cache calls without
6/// repeating entity and collection names at every query site. A future derive
7/// macro can generate the same implementation.
8///
9/// # Example
10///
11/// ```rust
12/// use hydracache_db::CacheEntity;
13///
14/// struct User;
15///
16/// impl CacheEntity for User {
17///     type Id = i64;
18///
19///     const ENTITY: &'static str = "user";
20///     const COLLECTION: Option<&'static str> = Some("users");
21/// }
22///
23/// assert_eq!(User::cache_key_for(&42), "user:42");
24/// assert_eq!(User::entity_tag_for(&42), "user:42");
25/// assert_eq!(User::collection_tag(), Some("users".to_owned()));
26/// ```
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}