1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy)]
5pub enum Progress {
6 Starting { total: u64 },
7 Resuming { current: u64, total: u64 },
8 Chunk { current: u64, total: u64 },
9 Complete { total: u64 },
10 Error,
11 Aborted,
12 Recovered,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum OverwriteMode {
18 Skip,
19 Force,
20 Prompt,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct ResumeInfo {
26 pub downloaded: u64,
27 pub total: u64,
28 pub etag: Option<String>,
29 pub last_modified: Option<String>,
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35
36 #[test]
37 fn test_progress_starting() {
38 let progress = Progress::Starting {
39 total: 1024,
40 };
41 match progress {
42 Progress::Starting {
43 total,
44 } => assert_eq!(total, 1024),
45 _ => panic!("Expected Progress::Starting"),
46 }
47 }
48
49 #[test]
50 fn test_progress_chunk() {
51 let progress = Progress::Chunk {
52 current: 512,
53 total: 1024,
54 };
55 match progress {
56 Progress::Chunk {
57 current,
58 total,
59 } => {
60 assert_eq!(current, 512);
61 assert_eq!(total, 1024);
62 }
63 _ => panic!("Expected Progress::Chunk"),
64 }
65 }
66
67 #[test]
68 fn test_progress_complete() {
69 let progress = Progress::Complete {
70 total: 1024,
71 };
72 match progress {
73 Progress::Complete {
74 total,
75 } => assert_eq!(total, 1024),
76 _ => panic!("Expected Progress::Complete"),
77 }
78 }
79
80 #[test]
81 fn test_progress_clone() {
82 let p1 = Progress::Starting {
83 total: 100,
84 };
85 let p2 = p1;
86 match (p1, p2) {
87 (
88 Progress::Starting {
89 total: t1,
90 },
91 Progress::Starting {
92 total: t2,
93 },
94 ) => {
95 assert_eq!(t1, t2);
96 }
97 _ => panic!("Clone failed"),
98 }
99 }
100
101 #[test]
102 fn test_overwrite_mode_equality() {
103 assert_eq!(OverwriteMode::Skip, OverwriteMode::Skip);
104 assert_eq!(OverwriteMode::Force, OverwriteMode::Force);
105 assert_eq!(OverwriteMode::Prompt, OverwriteMode::Prompt);
106
107 assert_ne!(OverwriteMode::Skip, OverwriteMode::Force);
108 assert_ne!(OverwriteMode::Force, OverwriteMode::Prompt);
109 assert_ne!(OverwriteMode::Skip, OverwriteMode::Prompt);
110 }
111
112 #[test]
113 fn test_overwrite_mode_clone() {
114 let mode1 = OverwriteMode::Force;
115 let mode2 = mode1;
116 assert_eq!(mode1, mode2);
117 }
118
119 #[test]
120 fn test_resume_info_with_etag() {
121 let info = ResumeInfo {
122 downloaded: 512,
123 total: 1024,
124 etag: Some("\"abc123\"".to_string()),
125 last_modified: None,
126 };
127
128 assert_eq!(info.downloaded, 512);
129 assert_eq!(info.total, 1024);
130 assert_eq!(info.etag, Some("\"abc123\"".to_string()));
131 assert_eq!(info.last_modified, None);
132 }
133
134 #[test]
135 fn test_resume_info_with_last_modified() {
136 let info = ResumeInfo {
137 downloaded: 256,
138 total: 1024,
139 etag: None,
140 last_modified: Some("Wed, 21 Oct 2015 07:28:00 GMT".to_string()),
141 };
142
143 assert_eq!(info.downloaded, 256);
144 assert_eq!(
145 info.last_modified,
146 Some("Wed, 21 Oct 2015 07:28:00 GMT".to_string())
147 );
148 }
149
150 #[test]
151 fn test_resume_info_serialize_deserialize() {
152 let info = ResumeInfo {
153 downloaded: 1024,
154 total: 2048,
155 etag: Some("etag-value".to_string()),
156 last_modified: Some("date".to_string()),
157 };
158
159 let json = serde_json::to_string(&info).unwrap();
160 let deserialized: ResumeInfo = serde_json::from_str(&json).unwrap();
161
162 assert_eq!(deserialized.downloaded, info.downloaded);
163 assert_eq!(deserialized.total, info.total);
164 assert_eq!(deserialized.etag, info.etag);
165 assert_eq!(deserialized.last_modified, info.last_modified);
166 }
167
168 #[test]
169 fn test_resume_info_clone() {
170 let info1 = ResumeInfo {
171 downloaded: 100,
172 total: 200,
173 etag: Some("tag".to_string()),
174 last_modified: None,
175 };
176
177 let info2 = info1.clone();
178 assert_eq!(info1.downloaded, info2.downloaded);
179 assert_eq!(info1.total, info2.total);
180 assert_eq!(info1.etag, info2.etag);
181 }
182}