1use std::process::ExitCode;
2
3use serde_json::json;
4use substrate::CmnUri;
5
6use crate::api::Output;
7
8use super::CacheDir;
9
10pub 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
54pub 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
79pub 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}