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