Skip to main content

hypha/cache/
commands.rs

1use std::process::ExitCode;
2
3use serde_json::json;
4use substrate::CmnUri;
5
6use crate::api::Output;
7
8use super::CacheDir;
9
10/// Handle the `cache list` command
11pub fn handle_list(out: &Output) -> ExitCode {
12    let cache = match CacheDir::new() {
13        Ok(cache) => cache,
14        Err(e) => return out.error_hypha(&e),
15    };
16    let spores = cache.list_all();
17
18    if spores.is_empty() {
19        let data = json!({
20            "count": 0,
21            "spores": [],
22            "total_size": 0,
23        });
24
25        return out.ok(data);
26    }
27
28    let total_size: u64 = spores.iter().map(|s| s.size).sum();
29
30    let spores_json: Vec<serde_json::Value> = spores
31        .iter()
32        .map(|s| {
33            json!({
34                "domain": s.domain,
35                "hash": s.hash,
36                "name": s.name,
37                "synopsis": s.synopsis,
38                "path": s.path.display().to_string(),
39                "size": s.size,
40                "verdict": s.verdict,
41            })
42        })
43        .collect();
44
45    let data = json!({
46        "count": spores.len(),
47        "spores": spores_json,
48        "total_size": total_size,
49    });
50
51    out.ok(data)
52}
53
54/// Handle the `cache clean` command
55pub fn handle_clean(out: &Output, all: bool) -> ExitCode {
56    let cache = match CacheDir::new() {
57        Ok(cache) => cache,
58        Err(e) => return out.error_hypha(&e),
59    };
60
61    if all {
62        match cache.clean_all() {
63            Ok(count) => {
64                let data = json!({
65                    "removed": count,
66                });
67                out.ok(data)
68            }
69            Err(e) => out.error_hypha(&e),
70        }
71    } else {
72        out.error(
73            "invalid_args",
74            "Use --all to remove all cached items. Age-based cleanup not yet implemented.",
75        )
76    }
77}
78
79/// Handle the `cache path` command
80pub fn handle_path(out: &Output, uri_str: &str) -> ExitCode {
81    let uri = match CmnUri::parse(uri_str) {
82        Ok(u) => u,
83        Err(e) => return out.error("uri_error", &e),
84    };
85
86    let hash = match &uri.hash {
87        Some(h) => h,
88        None => return out.error("uri_error", "spore URI must include a hash"),
89    };
90
91    let cache = match CacheDir::new() {
92        Ok(cache) => cache,
93        Err(e) => return out.error_hypha(&e),
94    };
95    let path = cache.spore_path(&uri.domain, hash);
96
97    if !path.exists() {
98        return out.error_hint(
99            "NOT_CACHED",
100            "Spore not cached",
101            Some(&format!("run: hypha taste {}", uri_str)),
102        );
103    }
104
105    let content_path = path.join("content");
106    let display_path = if content_path.exists() {
107        content_path
108    } else {
109        path.clone()
110    };
111
112    let data = json!({
113        "uri": uri_str,
114        "path": display_path.display().to_string(),
115    });
116
117    out.ok(data)
118}