02d8172
use std::time::Duration;
use ::cache::Cache;
use serde::Serialize;
use serde::de::DeserializeOwned;
use crate::share::errors::GitError;
pub const REV_TTL: Duration = Duration::from_secs(60);
pub const ANALYSIS_TTL: Duration = Duration::from_secs(600);
pub const IMMUTABLE_TTL: Duration = Duration::from_secs(30 * 24 * 3600);
pub fn sanitize_key(k: &str) -> String {
let mut out = String::with_capacity(k.len());
for c in k.chars() {
if c.is_ascii_alphanumeric() || matches!(c, '-' | '_' | '.' | ':' | '/') {
out.push(c);
} else {
out.push('_');
}
}
out
}
pub async fn cached_fetch<V, F, Fut>(
cache: &Cache,
key: &str,
ttl: Duration,
fetch: F,
) -> Result<V, GitError>
where
V: Serialize + DeserializeOwned,
F: FnOnce() -> Fut,
Fut: std::future::Future<Output = Result<V, GitError>>,
{
let sanitized = sanitize_key(key);
if let Ok(Some(cached)) = cache.get_json::<V>(&sanitized).await {
return Ok(cached);
}
let val = fetch().await?;
let _ = cache.set_json_ex(&sanitized, &val, ttl).await;
Ok(val)
}