1use std::time::Duration;
2
3use hydracache::{CacheKeyBuilder, CacheOptions, TagSet};
4
5use crate::CacheEntity;
6
7#[derive(Debug, Clone, Default, PartialEq, Eq)]
32pub struct QueryCachePolicy {
33 name: Option<String>,
34 key: Option<String>,
35 tags: TagSet,
36 ttl: Option<Duration>,
37}
38
39impl QueryCachePolicy {
40 pub fn new() -> Self {
42 Self::default()
43 }
44
45 pub fn named(name: impl Into<String>) -> Self {
47 Self::new().with_name(name)
48 }
49
50 pub fn name(&self) -> Option<&str> {
52 self.name.as_deref()
53 }
54
55 pub fn key_value(&self) -> Option<&str> {
57 self.key.as_deref()
58 }
59
60 pub fn tags_value(&self) -> &[String] {
62 self.tags.as_slice()
63 }
64
65 pub fn ttl_value(&self) -> Option<Duration> {
67 self.ttl
68 }
69
70 pub fn with_name(mut self, name: impl Into<String>) -> Self {
72 self.name = Some(name.into());
73 self
74 }
75
76 pub fn key(mut self, key: impl Into<String>) -> Self {
78 self.key = Some(key.into());
79 self
80 }
81
82 pub fn key_builder(self, key: CacheKeyBuilder) -> Self {
84 self.key(key.build_string())
85 }
86
87 pub fn for_entity(mut self, kind: impl ToString, id: impl ToString) -> Self {
89 let key = entity_key(kind, id);
90 self.key = Some(key.clone());
91 self.tags = self.tags.tag(key);
92 self
93 }
94
95 pub fn for_cache_entity<T>(mut self, id: T::Id) -> Self
97 where
98 T: CacheEntity,
99 {
100 let key = T::cache_key_for(&id);
101 self.key = Some(key);
102 self.tags = self.tags.tag(T::entity_tag_for(&id));
103 self.tags = append_optional_tag(self.tags, T::collection_tag());
104 self
105 }
106
107 pub fn collection(mut self, name: impl ToString) -> Self {
109 let tag = collection_tag(name);
110 self.key = Some(tag.clone());
111 self.tags = self.tags.tag(tag);
112 self
113 }
114
115 pub fn tag(mut self, tag: impl Into<String>) -> Self {
117 self.tags = self.tags.tag(tag);
118 self
119 }
120
121 pub fn collection_tag(mut self, name: impl ToString) -> Self {
123 self.tags = self.tags.tag(collection_tag(name));
124 self
125 }
126
127 pub fn tags<I, S>(mut self, tags: I) -> Self
129 where
130 I: IntoIterator<Item = S>,
131 S: Into<String>,
132 {
133 self.tags = self.tags.tags(tags);
134 self
135 }
136
137 pub fn tag_set(mut self, tags: TagSet) -> Self {
139 self.tags = tags;
140 self
141 }
142
143 pub fn ttl(mut self, ttl: Duration) -> Self {
145 self.ttl = Some(ttl);
146 self
147 }
148
149 pub(crate) fn cache_options(&self) -> CacheOptions {
150 let mut options = CacheOptions::new().tag_set(self.tags.clone());
151 if let Some(ttl) = self.ttl {
152 options = options.ttl(ttl);
153 }
154 options
155 }
156}
157
158pub(crate) fn entity_key(kind: impl ToString, id: impl ToString) -> String {
159 CacheKeyBuilder::new().entity(kind, id).build_string()
160}
161
162pub(crate) fn collection_tag(name: impl ToString) -> String {
163 CacheKeyBuilder::from_segment(name).build_string()
164}
165
166fn append_optional_tag(tags: TagSet, tag: Option<String>) -> TagSet {
167 match tag {
168 Some(tag) => tags.tag(tag),
169 None => tags,
170 }
171}