es_fluent_cli/generation/
cache.rs1use serde::{Deserialize, Serialize};
8use std::path::Path;
9
10#[derive(Debug, Default, Deserialize, Serialize)]
15pub struct MetadataCache {
16 pub cargo_lock_hash: String,
18 pub es_fluent_dep: String,
20 pub es_fluent_cli_helpers_dep: String,
22 pub target_dir: String,
24}
25
26impl MetadataCache {
27 const CACHE_FILE: &'static str = "metadata_cache.json";
28
29 pub fn load(temp_dir: &Path) -> Option<Self> {
31 let cache_path = temp_dir.join(Self::CACHE_FILE);
32 let content = std::fs::read_to_string(&cache_path).ok()?;
33 serde_json::from_str(&content).ok()
34 }
35
36 pub fn save(&self, temp_dir: &Path) -> std::io::Result<()> {
38 let cache_path = temp_dir.join(Self::CACHE_FILE);
39 let content = serde_json::to_string_pretty(self)?;
40 std::fs::write(cache_path, content)
41 }
42
43 pub fn hash_cargo_lock(workspace_root: &Path) -> Option<String> {
45 let lock_path = workspace_root.join("Cargo.lock");
46 let content = std::fs::read(&lock_path).ok()?;
47 Some(blake3::hash(&content).to_hex().to_string())
48 }
49
50 pub fn is_valid(&self, workspace_root: &Path) -> bool {
52 Self::hash_cargo_lock(workspace_root)
53 .map(|h| h == self.cargo_lock_hash)
54 .unwrap_or(false)
55 }
56}
57
58pub fn compute_content_hash(src_dir: &Path) -> String {
63 use blake3::Hasher;
64
65 let mut hasher = Hasher::new();
66 let mut files: Vec<std::path::PathBuf> = Vec::new();
67
68 if src_dir.exists() {
69 let walker = walkdir::WalkDir::new(src_dir);
70 for entry in walker.into_iter().filter_map(|e| e.ok()) {
71 let path = entry.path();
72 if path.is_file() && path.extension().is_some_and(|e| e == "rs") {
73 files.push(path.to_path_buf());
74 }
75 }
76 }
77
78 files.sort();
80
81 for path in files {
83 if let Ok(content) = std::fs::read(&path) {
84 hasher.update(path.to_string_lossy().as_bytes());
85 hasher.update(&content);
86 }
87 }
88
89 hasher.finalize().to_hex().to_string()
90}
91
92#[derive(Debug, Default, Deserialize, Serialize)]
96pub struct RunnerCache {
97 pub crate_hashes: std::collections::HashMap<String, String>,
99 pub runner_mtime: u64,
101 #[serde(default)]
104 pub cli_version: String,
105}
106
107impl RunnerCache {
108 const CACHE_FILE: &'static str = "runner_cache.json";
109
110 pub fn load(temp_dir: &Path) -> Option<Self> {
112 let cache_path = temp_dir.join(Self::CACHE_FILE);
113 let content = std::fs::read_to_string(&cache_path).ok()?;
114 serde_json::from_str(&content).ok()
115 }
116
117 pub fn save(&self, temp_dir: &Path) -> std::io::Result<()> {
119 let cache_path = temp_dir.join(Self::CACHE_FILE);
120 let content = serde_json::to_string_pretty(self)?;
121 std::fs::write(cache_path, content)
122 }
123}