use anyhow::{Result, bail};
use chrono::{DateTime, Utc};
use crate::cache::engine_profile::EngineProfile;
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct ArtifactMetadata {
pub schema_version: u32,
pub engine_profile_id: String,
pub wasmtime_version: String,
pub target_triple: String,
pub cpu_policy: String,
pub config_fingerprint: String,
pub wasm_digest: String,
pub artifact_bytes: u64,
pub created_at: String,
pub last_access_at: String,
pub hit_count: u64,
}
impl ArtifactMetadata {
pub fn new(profile: &EngineProfile, wasm_digest: String, artifact_bytes: u64) -> Self {
let now = Utc::now();
let ts = now.to_rfc3339();
Self {
schema_version: 1,
engine_profile_id: profile.engine_profile_id.clone(),
wasmtime_version: profile.wasmtime_version.clone(),
target_triple: profile.target_triple.clone(),
cpu_policy: profile.cpu_policy.as_str().to_string(),
config_fingerprint: profile.config_fingerprint.clone(),
wasm_digest,
artifact_bytes,
created_at: ts.clone(),
last_access_at: ts,
hit_count: 0,
}
}
pub fn validate_for_profile(&self, profile: &EngineProfile) -> Result<()> {
if self.schema_version != 1 {
bail!("cache metadata schema_version must be 1");
}
if self.engine_profile_id != profile.engine_profile_id {
bail!("cache metadata engine_profile_id mismatch");
}
if self.wasmtime_version != profile.wasmtime_version {
bail!("cache metadata wasmtime_version mismatch");
}
if self.target_triple != profile.target_triple {
bail!("cache metadata target_triple mismatch");
}
if self.cpu_policy != profile.cpu_policy.as_str() {
bail!("cache metadata cpu_policy mismatch");
}
if self.config_fingerprint != profile.config_fingerprint {
bail!("cache metadata config_fingerprint mismatch");
}
Ok(())
}
pub fn last_access_time(&self) -> Option<DateTime<Utc>> {
DateTime::parse_from_rfc3339(&self.last_access_at)
.ok()
.map(|dt| dt.with_timezone(&Utc))
.or_else(|| {
DateTime::parse_from_rfc3339(&self.created_at)
.ok()
.map(|dt| dt.with_timezone(&Utc))
})
}
pub fn touch(&mut self) {
self.last_access_at = Utc::now().to_rfc3339();
self.hit_count = self.hit_count.saturating_add(1);
}
}