arm_toolchain/toolchain/
remove.rs1use std::path::PathBuf;
2
3use tokio_util::sync::CancellationToken;
4
5use crate::toolchain::ToolchainError;
6use crate::{CheckCancellation, fs};
7
8pub enum RemoveProgress {
9 Start { total_bytes: u64 },
10 Progress { bytes_removed: u64 },
11 End,
12}
13
14pub async fn remove_dir_progress(
15 dir: PathBuf,
16 mut progress: impl FnMut(RemoveProgress),
17 cancel_token: &CancellationToken,
18) -> Result<(), ToolchainError> {
19 let mut items = vec![];
20 let total_bytes = enumerate_dir(dir, &mut items, cancel_token).await?;
21 let mut bytes_removed = 0;
22
23 progress(RemoveProgress::Start { total_bytes });
24
25 for item in items {
26 if item.sym {
27 if cfg!(windows) && item.dir {
28 fs::remove_dir(&item.path).await?;
29 } else {
30 fs::remove_file(&item.path).await?;
31 }
32 } else if item.dir {
33 fs::remove_dir(&item.path).await?;
34 } else {
35 fs::remove_file(&item.path).await?;
36 bytes_removed += item.size;
37 }
38
39 progress(RemoveProgress::Progress { bytes_removed });
40 }
41
42 progress(RemoveProgress::End);
43
44 Ok(())
45}
46
47async fn enumerate_dir(
48 path: PathBuf,
49 contents_vec: &mut Vec<Item>,
50 cancel_token: &CancellationToken,
51) -> Result<u64, ToolchainError> {
52 let mut bytes = 0;
53
54 let meta = fs::symlink_metadata(&path).await?;
55
56 if meta.is_symlink() {
57 contents_vec.push(Item {
58 path,
59 dir: meta.is_dir(),
60 sym: true,
61 size: meta.len(),
62 });
63 return Ok(meta.len());
64 }
65
66 if meta.is_file() {
67 contents_vec.push(Item {
68 path,
69 dir: false,
70 sym: false,
71 size: meta.len(),
72 });
73 return Ok(meta.len());
74 }
75
76 let mut read_dir = fs::read_dir(&path).await?;
77 while let Some(entry) = read_dir.next_entry().await? {
78 cancel_token.check_cancellation(ToolchainError::Cancelled)?;
79
80 let path = entry.path();
81 bytes += Box::pin(enumerate_dir(path, contents_vec, cancel_token)).await?;
82 }
83
84 contents_vec.push(Item {
85 path,
86 dir: true,
87 sym: false,
88 size: meta.len(),
89 });
90
91 Ok(bytes + meta.len())
92}
93
94struct Item {
95 path: PathBuf,
96 sym: bool,
97 dir: bool,
98 size: u64,
99}