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