mithril_client_cli/utils/
cardano_db.rs

1use anyhow::anyhow;
2use futures::Future;
3use indicatif::{MultiProgress, ProgressBar};
4use std::time::Duration;
5
6use super::CardanoDbDownloadCheckerError;
7use mithril_client::{MithrilError, MithrilResult};
8
9/// Utility functions for to the CardanoDb commands
10pub struct CardanoDbUtils;
11
12impl CardanoDbUtils {
13    /// Handle the error return by `check_prerequisites`
14    pub fn check_disk_space_error(error: MithrilError) -> MithrilResult<String> {
15        match error.downcast_ref::<CardanoDbDownloadCheckerError>() {
16            Some(CardanoDbDownloadCheckerError::NotEnoughSpaceForArchive { .. })
17            | Some(CardanoDbDownloadCheckerError::NotEnoughSpaceForUncompressedData { .. }) => {
18                Ok(format!("Warning: {}", error))
19            }
20            _ => Err(error),
21        }
22    }
23
24    /// Display a spinner while waiting for the result of a future
25    pub async fn wait_spinner<T>(
26        progress_bar: &MultiProgress,
27        future: impl Future<Output = MithrilResult<T>>,
28    ) -> MithrilResult<T> {
29        let pb = progress_bar.add(ProgressBar::new_spinner());
30        let spinner = async move {
31            loop {
32                pb.tick();
33                tokio::time::sleep(Duration::from_millis(50)).await;
34            }
35        };
36
37        tokio::select! {
38            _ = spinner => Err(anyhow!("timeout")),
39            res = future => res,
40        }
41    }
42
43    pub fn format_bytes_to_gigabytes(bytes: u64) -> String {
44        let size_in_giga = bytes as f64 / (1024.0 * 1024.0 * 1024.0);
45
46        format!("{:.2} GiB", size_in_giga)
47    }
48}
49
50#[cfg(test)]
51mod test {
52    use super::*;
53    use std::path::PathBuf;
54
55    #[test]
56    fn check_disk_space_error_should_return_warning_message_if_error_is_not_enough_space_for_archive(
57    ) {
58        let not_enough_space_error = CardanoDbDownloadCheckerError::NotEnoughSpaceForArchive {
59            left_space: 1_f64,
60            pathdir: PathBuf::new(),
61            archive_size: 2_f64,
62        };
63        let expected = format!("Warning: {}", not_enough_space_error);
64
65        let result = CardanoDbUtils::check_disk_space_error(anyhow!(not_enough_space_error))
66            .expect("check_disk_space_error should not error");
67
68        assert!(result.contains(&expected));
69    }
70
71    #[test]
72    fn check_disk_space_error_should_return_warning_message_if_error_is_not_enough_space_for_uncompressed_data(
73    ) {
74        let not_enough_space_error =
75            CardanoDbDownloadCheckerError::NotEnoughSpaceForUncompressedData {
76                left_space: 1_f64,
77                pathdir: PathBuf::new(),
78                db_size: 2_f64,
79            };
80        let expected = format!("Warning: {}", not_enough_space_error);
81
82        let result = CardanoDbUtils::check_disk_space_error(anyhow!(not_enough_space_error))
83            .expect("check_disk_space_error should not error");
84
85        assert!(result.contains(&expected));
86    }
87
88    #[test]
89    fn check_disk_space_error_should_return_error_if_error_is_not_error_not_enough_space() {
90        let error = CardanoDbDownloadCheckerError::UnpackDirectoryNotEmpty(PathBuf::new());
91
92        let error = CardanoDbUtils::check_disk_space_error(anyhow!(error))
93            .expect_err("check_disk_space_error should fail");
94
95        assert!(
96            matches!(
97                error.downcast_ref::<CardanoDbDownloadCheckerError>(),
98                Some(CardanoDbDownloadCheckerError::UnpackDirectoryNotEmpty(_))
99            ),
100            "Unexpected error: {:?}",
101            error
102        );
103    }
104
105    #[test]
106    fn format_bytes_to_gigabytes_zero() {
107        let one_gigabyte = 1024 * 1024 * 1024;
108
109        assert_eq!(CardanoDbUtils::format_bytes_to_gigabytes(0), "0.00 GiB");
110
111        assert_eq!(
112            CardanoDbUtils::format_bytes_to_gigabytes(one_gigabyte),
113            "1.00 GiB"
114        );
115
116        assert_eq!(
117            CardanoDbUtils::format_bytes_to_gigabytes(one_gigabyte / 2),
118            "0.50 GiB"
119        );
120
121        assert_eq!(
122            CardanoDbUtils::format_bytes_to_gigabytes(one_gigabyte * 10),
123            "10.00 GiB"
124        );
125    }
126}