use serde::Serialize;
use std::{fmt, path::PathBuf};
pub const CACHE_STATUS_REPORT_SCHEMA_VERSION: u32 = 2;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum CacheValidationStatus {
#[serde(rename = "ok")]
Valid,
Invalid,
}
impl CacheValidationStatus {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Valid => "ok",
Self::Invalid => "invalid",
}
}
}
impl fmt::Display for CacheValidationStatus {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.as_str())
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum CacheFileStatus {
Fresh,
Stale,
Unmanaged,
Invalid,
}
impl CacheFileStatus {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Fresh => "fresh",
Self::Stale => "stale",
Self::Unmanaged => "unmanaged",
Self::Invalid => "invalid",
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum CacheRefreshLockStatus {
Active,
Stale,
Invalid,
}
impl CacheRefreshLockStatus {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Active => "active",
Self::Stale => "stale",
Self::Invalid => "invalid",
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct CacheStatusRequest {
pub cache_root: PathBuf,
pub now_unix_secs: u64,
}
impl CacheStatusRequest {
#[must_use]
pub fn new(cache_root: impl Into<PathBuf>, now_unix_secs: u64) -> Self {
Self {
cache_root: cache_root.into(),
now_unix_secs,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct CacheStatusReport {
pub schema_version: u32,
pub cache_root: String,
pub inspected_at: String,
pub cache_root_found: bool,
pub scan_limit: usize,
pub truncated: bool,
pub cache_count: usize,
pub fresh_count: usize,
pub stale_count: usize,
pub unmanaged_count: usize,
pub invalid_count: usize,
pub total_size_bytes: u64,
pub caches: Vec<CacheStatusRow>,
pub refresh_lock_count: usize,
pub active_refresh_lock_count: usize,
pub stale_refresh_lock_count: usize,
pub invalid_refresh_lock_count: usize,
pub refresh_lock_size_bytes: u64,
pub refresh_locks: Vec<CacheRefreshLockStatusRow>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct CacheStatusRow {
pub component: String,
pub cache_path: String,
pub relative_path: String,
pub status: CacheFileStatus,
pub schema_version: Option<u32>,
pub network: Option<String>,
pub fetched_at: Option<String>,
pub age_seconds: Option<u64>,
pub stale_after_seconds: Option<u64>,
pub size_bytes: u64,
pub error: Option<String>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct CacheRefreshLockStatusRow {
pub component: String,
pub refresh_lock_path: String,
pub relative_path: String,
pub status: CacheRefreshLockStatus,
pub schema_version: Option<u32>,
pub network: Option<String>,
pub pid: Option<u32>,
pub started_at_unix_ms: Option<u64>,
pub started_at: Option<String>,
pub age_seconds: Option<u64>,
pub stale_after_seconds: Option<u64>,
pub target_path: Option<String>,
pub size_bytes: u64,
pub error: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn typed_statuses_keep_the_existing_json_labels() {
for (status, expected) in [
(CacheValidationStatus::Valid, "ok"),
(CacheValidationStatus::Invalid, "invalid"),
] {
assert_eq!(status.as_str(), expected);
assert_eq!(status.to_string(), expected);
assert_eq!(
serde_json::to_value(status).expect("serialize cache validation status"),
serde_json::json!(expected)
);
}
for (status, expected) in [
(CacheFileStatus::Fresh, "fresh"),
(CacheFileStatus::Stale, "stale"),
(CacheFileStatus::Unmanaged, "unmanaged"),
(CacheFileStatus::Invalid, "invalid"),
] {
assert_eq!(status.as_str(), expected);
assert_eq!(
serde_json::to_value(status).expect("serialize cache status"),
serde_json::json!(expected)
);
}
for (status, expected) in [
(CacheRefreshLockStatus::Active, "active"),
(CacheRefreshLockStatus::Stale, "stale"),
(CacheRefreshLockStatus::Invalid, "invalid"),
] {
assert_eq!(status.as_str(), expected);
assert_eq!(
serde_json::to_value(status).expect("serialize refresh-lock status"),
serde_json::json!(expected)
);
}
}
}