use std::time::Duration;
use hydracache::{CacheKeyBuilder, CacheOptions, TagSet};
use crate::CacheEntity;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct QueryCachePolicy {
name: Option<String>,
key: Option<String>,
tags: TagSet,
ttl: Option<Duration>,
}
impl QueryCachePolicy {
pub fn new() -> Self {
Self::default()
}
pub fn named(name: impl Into<String>) -> Self {
Self::new().with_name(name)
}
pub fn name(&self) -> Option<&str> {
self.name.as_deref()
}
pub fn key_value(&self) -> Option<&str> {
self.key.as_deref()
}
pub fn tags_value(&self) -> &[String] {
self.tags.as_slice()
}
pub fn ttl_value(&self) -> Option<Duration> {
self.ttl
}
pub fn with_name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn key(mut self, key: impl Into<String>) -> Self {
self.key = Some(key.into());
self
}
pub fn key_builder(self, key: CacheKeyBuilder) -> Self {
self.key(key.build_string())
}
pub fn for_entity(mut self, kind: impl ToString, id: impl ToString) -> Self {
let key = entity_key(kind, id);
self.key = Some(key.clone());
self.tags = self.tags.tag(key);
self
}
pub fn for_cache_entity<T>(mut self, id: T::Id) -> Self
where
T: CacheEntity,
{
let key = T::cache_key_for(&id);
self.key = Some(key);
self.tags = self.tags.tag(T::entity_tag_for(&id));
self.tags = append_optional_tag(self.tags, T::collection_tag());
self
}
pub fn collection(mut self, name: impl ToString) -> Self {
let tag = collection_tag(name);
self.key = Some(tag.clone());
self.tags = self.tags.tag(tag);
self
}
pub fn tag(mut self, tag: impl Into<String>) -> Self {
self.tags = self.tags.tag(tag);
self
}
pub fn collection_tag(mut self, name: impl ToString) -> Self {
self.tags = self.tags.tag(collection_tag(name));
self
}
pub fn tags<I, S>(mut self, tags: I) -> Self
where
I: IntoIterator<Item = S>,
S: Into<String>,
{
self.tags = self.tags.tags(tags);
self
}
pub fn tag_set(mut self, tags: TagSet) -> Self {
self.tags = tags;
self
}
pub fn ttl(mut self, ttl: Duration) -> Self {
self.ttl = Some(ttl);
self
}
pub(crate) fn cache_options(&self) -> CacheOptions {
let mut options = CacheOptions::new().tag_set(self.tags.clone());
if let Some(ttl) = self.ttl {
options = options.ttl(ttl);
}
options
}
}
pub(crate) fn entity_key(kind: impl ToString, id: impl ToString) -> String {
CacheKeyBuilder::new().entity(kind, id).build_string()
}
pub(crate) fn collection_tag(name: impl ToString) -> String {
CacheKeyBuilder::from_segment(name).build_string()
}
fn append_optional_tag(tags: TagSet, tag: Option<String>) -> TagSet {
match tag {
Some(tag) => tags.tag(tag),
None => tags,
}
}