aperture_cli/engine/
loader.rs1use crate::cache::metadata::CacheMetadataManager;
2use crate::cache::models::{CachedSpec, CACHE_FORMAT_VERSION};
3use crate::error::Error;
4use crate::fs::OsFileSystem;
5use std::fs;
6use std::path::Path;
7
8pub fn load_cached_spec<P: AsRef<Path>>(
24 cache_dir: P,
25 spec_name: &str,
26) -> Result<CachedSpec, Error> {
27 let fs = OsFileSystem;
29 let metadata_manager = CacheMetadataManager::new(&fs);
30
31 match metadata_manager.check_spec_version(&cache_dir, spec_name) {
33 Ok(true) => {
34 load_cached_spec_without_version_check(&cache_dir, spec_name)
36 }
37 Ok(false) => {
38 load_cached_spec_with_version_check(&cache_dir, spec_name)
40 }
41 Err(_) => {
42 load_cached_spec_with_version_check(&cache_dir, spec_name)
44 }
45 }
46}
47
48fn load_cached_spec_without_version_check<P: AsRef<Path>>(
50 cache_dir: P,
51 spec_name: &str,
52) -> Result<CachedSpec, Error> {
53 let cache_path = cache_dir
54 .as_ref()
55 .join(format!("{spec_name}{}", crate::constants::FILE_EXT_BIN));
56
57 if !cache_path.exists() {
58 return Err(Error::cached_spec_not_found(spec_name));
59 }
60
61 let cache_data = fs::read(&cache_path)
62 .map_err(|e| Error::io_error(format!("Failed to read cache file: {e}")))?;
63 bincode::deserialize(&cache_data)
64 .map_err(|e| Error::cached_spec_corrupted(spec_name, e.to_string()))
65}
66
67fn load_cached_spec_with_version_check<P: AsRef<Path>>(
69 cache_dir: P,
70 spec_name: &str,
71) -> Result<CachedSpec, Error> {
72 let cache_path = cache_dir
73 .as_ref()
74 .join(format!("{spec_name}{}", crate::constants::FILE_EXT_BIN));
75
76 if !cache_path.exists() {
77 return Err(Error::cached_spec_not_found(spec_name));
78 }
79
80 let cache_data = fs::read(&cache_path)
81 .map_err(|e| Error::io_error(format!("Failed to read cache file: {e}")))?;
82 let cached_spec: CachedSpec = bincode::deserialize(&cache_data)
83 .map_err(|e| Error::cached_spec_corrupted(spec_name, e.to_string()))?;
84
85 if cached_spec.cache_format_version != CACHE_FORMAT_VERSION {
87 return Err(Error::cache_version_mismatch(
88 spec_name,
89 cached_spec.cache_format_version,
90 CACHE_FORMAT_VERSION,
91 ));
92 }
93
94 Ok(cached_spec)
95}