1use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9
10#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
12#[serde(tag = "status")]
13pub enum CacheCrateOutput {
14 #[serde(rename = "success")]
16 Success {
17 message: String,
18 #[serde(rename = "crate")]
19 crate_name: String,
20 version: String,
21 #[serde(skip_serializing_if = "Option::is_none")]
22 members: Option<Vec<String>>,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 results: Option<Vec<String>>,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 updated: Option<bool>,
27 },
28 #[serde(rename = "partial_success")]
30 PartialSuccess {
31 message: String,
32 #[serde(rename = "crate")]
33 crate_name: String,
34 version: String,
35 members: Vec<String>,
36 results: Vec<String>,
37 errors: Vec<String>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 updated: Option<bool>,
40 },
41 #[serde(rename = "workspace_detected")]
43 WorkspaceDetected {
44 message: String,
45 #[serde(rename = "crate")]
46 crate_name: String,
47 version: String,
48 workspace_members: Vec<String>,
49 example_usage: String,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 updated: Option<bool>,
52 },
53 #[serde(rename = "error")]
55 Error { error: String },
56}
57
58impl CacheCrateOutput {
59 pub fn to_json(&self) -> String {
61 serde_json::to_string(self)
62 .unwrap_or_else(|_| r#"{"error":"Failed to serialize response"}"#.to_string())
63 }
64
65 pub fn is_success(&self) -> bool {
67 matches!(self, CacheCrateOutput::Success { .. })
68 }
69
70 pub fn is_error(&self) -> bool {
72 matches!(self, CacheCrateOutput::Error { .. })
73 }
74
75 pub fn is_workspace_detected(&self) -> bool {
77 matches!(self, CacheCrateOutput::WorkspaceDetected { .. })
78 }
79}
80
81#[derive(Debug, Serialize, Deserialize, PartialEq)]
83pub struct RemoveCrateOutput {
84 pub status: String,
85 pub message: String,
86 #[serde(rename = "crate")]
87 pub crate_name: String,
88 pub version: String,
89}
90
91impl RemoveCrateOutput {
92 pub fn to_json(&self) -> String {
94 serde_json::to_string(self)
95 .unwrap_or_else(|_| r#"{"error":"Failed to serialize response"}"#.to_string())
96 }
97}
98
99#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
101pub struct VersionInfo {
102 pub version: String,
103 pub cached_at: String,
104 pub doc_generated: bool,
105 pub size_bytes: u64,
106 pub size_human: String,
107 #[serde(skip_serializing_if = "Option::is_none")]
108 pub members: Option<Vec<String>>,
109}
110
111#[derive(Debug, Serialize, Deserialize, PartialEq)]
113pub struct SizeInfo {
114 pub bytes: u64,
115 pub human: String,
116}
117
118#[derive(Debug, Serialize, Deserialize, PartialEq)]
120pub struct ListCachedCratesOutput {
121 pub crates: HashMap<String, Vec<VersionInfo>>,
122 pub total_crates: usize,
123 pub total_versions: usize,
124 pub total_size: SizeInfo,
125}
126
127impl ListCachedCratesOutput {
128 pub fn to_json(&self) -> String {
130 serde_json::to_string(self)
131 .unwrap_or_else(|_| r#"{"error":"Failed to serialize response"}"#.to_string())
132 }
133}
134
135#[derive(Debug, Serialize, Deserialize, PartialEq)]
137pub struct ListCrateVersionsOutput {
138 #[serde(rename = "crate")]
139 pub crate_name: String,
140 pub versions: Vec<VersionInfo>,
141 pub count: usize,
142}
143
144impl ListCrateVersionsOutput {
145 pub fn to_json(&self) -> String {
147 serde_json::to_string(self)
148 .unwrap_or_else(|_| r#"{"error":"Failed to serialize response"}"#.to_string())
149 }
150}
151
152#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
154pub struct CrateMetadata {
155 pub crate_name: String,
156 pub version: String,
157 pub cached: bool,
158 pub analyzed: bool,
159 #[serde(skip_serializing_if = "Option::is_none")]
160 pub cache_size_bytes: Option<u64>,
161 #[serde(skip_serializing_if = "Option::is_none")]
162 pub cache_size_human: Option<String>,
163 #[serde(skip_serializing_if = "Option::is_none")]
164 pub member: Option<String>,
165 #[serde(skip_serializing_if = "Option::is_none")]
166 pub workspace_members: Option<Vec<String>>,
167}
168
169#[derive(Debug, Serialize, Deserialize, PartialEq)]
171pub struct GetCratesMetadataOutput {
172 pub metadata: Vec<CrateMetadata>,
173 pub total_queried: usize,
174 pub total_cached: usize,
175}
176
177impl GetCratesMetadataOutput {
178 pub fn to_json(&self) -> String {
180 serde_json::to_string(self)
181 .unwrap_or_else(|_| r#"{"error":"Failed to serialize response"}"#.to_string())
182 }
183}
184
185#[derive(Debug, Serialize, Deserialize, PartialEq)]
187pub struct ErrorOutput {
188 pub error: String,
189}
190
191impl ErrorOutput {
192 pub fn new(message: impl Into<String>) -> Self {
194 Self {
195 error: message.into(),
196 }
197 }
198
199 pub fn to_json(&self) -> String {
201 serde_json::to_string(self)
202 .unwrap_or_else(|_| r#"{"error":"Failed to serialize error"}"#.to_string())
203 }
204}
205
206#[cfg(test)]
207mod tests {
208 use super::*;
209
210 #[test]
211 fn test_cache_crate_output_serialization() {
212 let output = CacheCrateOutput::Success {
213 message: "Successfully cached test-crate-1.0.0".to_string(),
214 crate_name: "test-crate".to_string(),
215 version: "1.0.0".to_string(),
216 members: None,
217 results: None,
218 updated: None,
219 };
220
221 let json = output.to_json();
222 let deserialized: CacheCrateOutput = serde_json::from_str(&json).unwrap();
223 assert_eq!(output, deserialized);
224 assert!(deserialized.is_success());
225 }
226
227 #[test]
228 fn test_workspace_detected_output() {
229 let output = CacheCrateOutput::WorkspaceDetected {
230 message: "This is a workspace crate".to_string(),
231 crate_name: "workspace".to_string(),
232 version: "1.0.0".to_string(),
233 workspace_members: vec!["member1".to_string(), "member2".to_string()],
234 example_usage: "example".to_string(),
235 updated: None,
236 };
237
238 assert!(output.is_workspace_detected());
239 assert!(!output.is_success());
240 assert!(!output.is_error());
241 }
242
243 #[test]
244 fn test_error_output() {
245 let output = ErrorOutput::new("Something went wrong");
246 let json = output.to_json();
247 let deserialized: ErrorOutput = serde_json::from_str(&json).unwrap();
248 assert_eq!(output, deserialized);
249 }
250}