1use crate::cli::cache::CacheOptions;
2use crate::config::ConfigProperties;
3use crate::error::GRError;
4use crate::Result;
5use std::fmt;
6use std::sync::Arc;
7
8pub fn execute(options: CacheOptions, config: Arc<dyn ConfigProperties>) -> Result<()> {
9 match options {
10 CacheOptions::Info => {
11 let size = get_cache_directory_size(&config)?;
12 println!("Location: {}", config.cache_location().unwrap_or("Not set"));
13 println!("Size: {}", BytesToHumanReadable::from(size));
14 }
15 }
16 Ok(())
17}
18
19struct BytesToHumanReadable(u64);
20
21impl From<u64> for BytesToHumanReadable {
22 fn from(size: u64) -> Self {
23 BytesToHumanReadable(size)
24 }
25}
26
27impl fmt::Display for BytesToHumanReadable {
28 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29 let size = self.0;
30 let suffixes = ["B", "KB", "MB", "GB"];
31 let suffix_len = suffixes.len();
32 let mut size = size as f64;
33 let mut i = 0;
34 while size >= 1024.0 && i < suffix_len - 1 {
35 size /= 1024.0;
36 i += 1;
37 }
38 write!(f, "{:.2} {}", size, suffixes[i])
39 }
40}
41
42fn get_cache_directory_size(config: &Arc<dyn ConfigProperties>) -> Result<u64> {
43 if let Some(path) = config.cache_location() {
44 let mut size = 0;
45 for entry in std::fs::read_dir(path)? {
46 let entry = entry?;
47 let metadata = entry.metadata()?;
48 size += metadata.len();
49 }
50 return Ok(size);
51 }
52 Err(GRError::ConfigurationNotFound.into())
53}
54
55#[cfg(test)]
56mod test {
57 use super::*;
58
59 use crate::config::ConfigProperties;
60 use std::fs::File;
61 use std::io::Write;
62 use tempfile::{tempdir, TempDir};
63
64 #[test]
65 fn test_bytes_display() {
66 let test_table = vec![
67 (0, "0.00 B"),
68 (1024, "1.00 KB"),
69 (1024 * 1024, "1.00 MB"),
70 (1024 * 1024 * 1024, "1.00 GB"),
71 ];
72 for (size, expected) in test_table {
73 let actual = BytesToHumanReadable::from(size).to_string();
74 assert_eq!(expected, actual);
75 }
76 }
77
78 struct ConfigMock {
79 tmp_dir: String,
80 }
81
82 impl ConfigMock {
83 fn new(tmp_dir: &TempDir) -> Self {
84 Self {
85 tmp_dir: tmp_dir.path().to_str().unwrap().to_string(),
86 }
87 }
88 }
89
90 impl ConfigProperties for ConfigMock {
91 fn cache_location(&self) -> Option<&str> {
92 Some(&self.tmp_dir)
93 }
94
95 fn api_token(&self) -> &str {
96 todo!()
97 }
98 }
99
100 #[test]
101 fn test_get_size_of_cached_data() {
102 let dir = tempdir().unwrap();
103 let file_path = dir.path().join("test_file");
104 let mut file = File::create(&file_path).unwrap();
105 file.write_all(&[0; 10]).unwrap();
106 let config: Arc<dyn ConfigProperties> = Arc::new(ConfigMock::new(&dir));
107 let size = get_cache_directory_size(&config).unwrap();
108 assert_eq!(size, 10);
109 }
110}