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!("{size_in_giga:.2} GiB")
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: {error:?}"
101        );
102    }
103
104    #[test]
105    fn format_bytes_to_gigabytes_zero() {
106        let one_gigabyte = 1024 * 1024 * 1024;
107
108        assert_eq!(CardanoDbUtils::format_bytes_to_gigabytes(0), "0.00 GiB");
109
110        assert_eq!(
111            CardanoDbUtils::format_bytes_to_gigabytes(one_gigabyte),
112            "1.00 GiB"
113        );
114
115        assert_eq!(
116            CardanoDbUtils::format_bytes_to_gigabytes(one_gigabyte / 2),
117            "0.50 GiB"
118        );
119
120        assert_eq!(
121            CardanoDbUtils::format_bytes_to_gigabytes(one_gigabyte * 10),
122            "10.00 GiB"
123        );
124    }
125}